blob: 498c57ea5d32c2c0176aea4ca0f429a2eded85b6 [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>
Dean Anderson38f993a2008-06-26 23:15:51 -030050#include <linux/vmalloc.h>
51#include <linux/usb.h>
52
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -030053#define S2255_VERSION "1.22.1"
Dean Anderson38f993a2008-06-26 23:15:51 -030054#define FIRMWARE_FILE_NAME "f2255usb.bin"
55
Dean Anderson22b88d42008-08-29 15:33:19 -030056/* default JPEG quality */
57#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030058/* vendor request in */
59#define S2255_VR_IN 0
60/* vendor request out */
61#define S2255_VR_OUT 1
62/* firmware query */
63#define S2255_VR_FW 0x30
64/* USB endpoint number for configuring the device */
65#define S2255_CONFIG_EP 2
66/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030067#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030068/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030069#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson38f993a2008-06-26 23:15:51 -030070#define S2255_DEF_BUFS 16
Dean Anderson14d96262008-08-25 13:58:55 -030071#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030072#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030073#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
74#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
75#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
76#define S2255_RESPONSE_FW cpu_to_le32(0x10)
77#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030078#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030079#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030080#define SYS_FRAMES 4
81/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030082#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
83#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030084#define LINE_SZ_4CIFS_NTSC 640
85#define LINE_SZ_2CIFS_NTSC 640
86#define LINE_SZ_1CIFS_NTSC 320
87#define LINE_SZ_4CIFS_PAL 704
88#define LINE_SZ_2CIFS_PAL 704
89#define LINE_SZ_1CIFS_PAL 352
90#define NUM_LINES_4CIFS_NTSC 240
91#define NUM_LINES_2CIFS_NTSC 240
92#define NUM_LINES_1CIFS_NTSC 240
93#define NUM_LINES_4CIFS_PAL 288
94#define NUM_LINES_2CIFS_PAL 288
95#define NUM_LINES_1CIFS_PAL 288
96#define LINE_SZ_DEF 640
97#define NUM_LINES_DEF 240
98
99
100/* predefined settings */
101#define FORMAT_NTSC 1
102#define FORMAT_PAL 2
103
104#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
105#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
106#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300107/* SCALE_4CIFSI is the 2 fields interpolated into one */
108#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300109
110#define COLOR_YUVPL 1 /* YUV planar */
111#define COLOR_YUVPK 2 /* YUV packed */
112#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300113#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300114
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300115#define MASK_COLOR 0x000000ff
116#define MASK_JPG_QUALITY 0x0000ff00
117#define MASK_INPUT_TYPE 0x000f0000
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300118/* frame decimation. */
Dean Anderson38f993a2008-06-26 23:15:51 -0300119#define FDEC_1 1 /* capture every frame. default */
120#define FDEC_2 2 /* capture every 2nd frame */
121#define FDEC_3 3 /* capture every 3rd frame */
122#define FDEC_5 5 /* capture every 5th frame */
123
124/*-------------------------------------------------------
125 * Default mode parameters.
126 *-------------------------------------------------------*/
127#define DEF_SCALE SCALE_4CIFS
128#define DEF_COLOR COLOR_YUVPL
129#define DEF_FDEC FDEC_1
130#define DEF_BRIGHT 0
131#define DEF_CONTRAST 0x5c
132#define DEF_SATURATION 0x80
133#define DEF_HUE 0
134
135/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300136#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
Dan Carpenter3b2a6302012-02-17 02:44:10 -0300137#define CMD_2255 0xc2255000
Dean Anderson3fa00602010-03-04 20:47:33 -0300138#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
139#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
140#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
141#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300142
143struct s2255_mode {
144 u32 format; /* input video format (NTSC, PAL) */
145 u32 scale; /* output video scale */
146 u32 color; /* output video color format */
147 u32 fdec; /* frame decimation */
148 u32 bright; /* brightness */
149 u32 contrast; /* contrast */
150 u32 saturation; /* saturation */
151 u32 hue; /* hue (NTSC only)*/
152 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
153 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
154 u32 restart; /* if DSP requires restart */
155};
156
Dean Anderson14d96262008-08-25 13:58:55 -0300157
158#define S2255_READ_IDLE 0
159#define S2255_READ_FRAME 1
160
Dean Anderson38f993a2008-06-26 23:15:51 -0300161/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300162struct s2255_framei {
163 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300164 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300165 void *lpvbits; /* image data */
166 unsigned long cur_size; /* current data copied to it */
167};
168
169/* image buffer structure */
170struct s2255_bufferi {
171 unsigned long dwFrames; /* number of frames in buffer */
172 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
173};
174
175#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
176 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300177 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300178
179struct s2255_dmaqueue {
180 struct list_head active;
Dean Anderson38f993a2008-06-26 23:15:51 -0300181 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300182};
183
184/* for firmware loading, fw_state */
185#define S2255_FW_NOTLOADED 0
186#define S2255_FW_LOADED_DSPWAIT 1
187#define S2255_FW_SUCCESS 2
188#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300189#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300190#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300191/* 2255 read states */
192#define S2255_READ_IDLE 0
193#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300194struct s2255_fw {
195 int fw_loaded;
196 int fw_size;
197 struct urb *fw_urb;
198 atomic_t fw_state;
199 void *pfw_data;
200 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300201 const struct firmware *fw;
202};
203
204struct s2255_pipeinfo {
205 u32 max_transfer_size;
206 u32 cur_transfer_size;
207 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300208 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300209 void *stream_urb;
210 void *dev; /* back pointer to s2255_dev struct*/
211 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300212 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300213};
214
215struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300216struct s2255_dev;
217
218struct s2255_channel {
219 struct video_device vdev;
220 int resources;
221 struct s2255_dmaqueue vidq;
222 struct s2255_bufferi buffer;
223 struct s2255_mode mode;
224 /* jpeg compression */
225 struct v4l2_jpegcompression jc;
226 /* capture parameters (for high quality mode full size) */
227 struct v4l2_captureparm cap_parm;
228 int cur_frame;
229 int last_frame;
230
231 int b_acquire;
232 /* allocated image size */
233 unsigned long req_image_size;
234 /* received packet size */
235 unsigned long pkt_size;
236 int bad_payload;
237 unsigned long frame_count;
238 /* if JPEG image */
239 int jpg_size;
240 /* if channel configured to default state */
241 int configured;
242 wait_queue_head_t wait_setmode;
243 int setmode_ready;
244 /* video status items */
245 int vidstatus;
246 wait_queue_head_t wait_vidstatus;
247 int vidstatus_ready;
248 unsigned int width;
249 unsigned int height;
250 const struct s2255_fmt *fmt;
251 int idx; /* channel number on device, 0-3 */
252};
253
Dean Anderson38f993a2008-06-26 23:15:51 -0300254
255struct s2255_dev {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300256 struct s2255_channel channel[MAX_CHANNELS];
Dean Anderson65c6edb2010-04-20 17:21:32 -0300257 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300258 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300259 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300260 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson38f993a2008-06-26 23:15:51 -0300261 struct usb_device *udev;
262 struct usb_interface *interface;
263 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300264 struct timer_list timer;
265 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300266 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300267 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300268 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300269 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300270 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300271 /* dsp firmware version (f2255usb.bin) */
272 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300273 u16 pid; /* product id */
Dean Anderson38f993a2008-06-26 23:15:51 -0300274};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300275
Dean Anderson65c6edb2010-04-20 17:21:32 -0300276static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
277{
278 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
279}
Dean Anderson38f993a2008-06-26 23:15:51 -0300280
281struct s2255_fmt {
282 char *name;
283 u32 fourcc;
284 int depth;
285};
286
287/* buffer for one video frame */
288struct s2255_buffer {
289 /* common v4l buffer stuff -- must be first */
290 struct videobuf_buffer vb;
291 const struct s2255_fmt *fmt;
292};
293
294struct s2255_fh {
295 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300296 struct videobuf_queue vb_vidq;
297 enum v4l2_buf_type type;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300298 struct s2255_channel *channel;
299 int resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300300};
301
Dean Andersonabce21f2009-04-23 16:04:41 -0300302/* current cypress EEPROM firmware version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300303#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
Dean Anderson4de39f52010-03-03 19:39:19 -0300304/* current DSP FW version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300305#define S2255_CUR_DSP_FWVER 10104
Dean Anderson4de39f52010-03-03 19:39:19 -0300306/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300307#define S2255_MIN_DSP_STATUS 5
308#define S2255_MIN_DSP_COLORFILTER 8
Dean Anderson38f993a2008-06-26 23:15:51 -0300309#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300310
311/* private V4L2 controls */
312
313/*
314 * The following chart displays how COLORFILTER should be set
315 * =========================================================
316 * = fourcc = COLORFILTER =
317 * = ===============================
318 * = = 0 = 1 =
319 * =========================================================
320 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
321 * = = s-video or = composite =
322 * = = B/W camera = input =
323 * =========================================================
324 * = other = color, svideo = color, =
325 * = = = composite =
326 * =========================================================
327 *
328 * Notes:
329 * channels 0-3 on 2255 are composite
330 * channels 0-1 on 2257 are composite, 2-3 are s-video
331 * If COLORFILTER is 0 with a composite color camera connected,
332 * the output will appear monochrome but hatching
333 * will occur.
334 * COLORFILTER is different from "color killer" and "color effects"
335 * for reasons above.
336 */
337#define S2255_V4L2_YC_ON 1
338#define S2255_V4L2_YC_OFF 0
339#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
340
Dean Anderson38f993a2008-06-26 23:15:51 -0300341/* frame prefix size (sent once every frame) */
342#define PREFIX_SIZE 512
343
344/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300345static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300346
Dean Anderson38f993a2008-06-26 23:15:51 -0300347static int debug;
348static int *s2255_debug = &debug;
349
350static int s2255_start_readpipe(struct s2255_dev *dev);
351static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300352static int s2255_start_acquire(struct s2255_channel *channel);
353static int s2255_stop_acquire(struct s2255_channel *channel);
354static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
355 int jpgsize);
356static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300357static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300358static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300359static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300360static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
361 u16 index, u16 value, void *buf,
362 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300363
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300364/* dev_err macro with driver name */
365#define S2255_DRIVER_NAME "s2255"
366#define s2255_dev_err(dev, fmt, arg...) \
367 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
368
Dean Anderson38f993a2008-06-26 23:15:51 -0300369#define dprintk(level, fmt, arg...) \
370 do { \
371 if (*s2255_debug >= (level)) { \
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300372 printk(KERN_DEBUG S2255_DRIVER_NAME \
373 ": " fmt, ##arg); \
Dean Anderson38f993a2008-06-26 23:15:51 -0300374 } \
375 } while (0)
376
Dean Anderson38f993a2008-06-26 23:15:51 -0300377static struct usb_driver s2255_driver;
378
Dean Anderson38f993a2008-06-26 23:15:51 -0300379/* Declare static vars that will be used as parameters */
380static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
381
382/* start video number */
383static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
384
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300385/* Enable jpeg capture. */
386static int jpeg_enable = 1;
387
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300388module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300389MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300390module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300391MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300392module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300393MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300394module_param(jpeg_enable, int, 0644);
395MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
Dean Anderson38f993a2008-06-26 23:15:51 -0300396
397/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300398#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300399static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300400 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
401 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300402 { } /* Terminating entry */
403};
404MODULE_DEVICE_TABLE(usb, s2255_table);
405
Dean Anderson38f993a2008-06-26 23:15:51 -0300406#define BUFFER_TIMEOUT msecs_to_jiffies(400)
407
Dean Anderson38f993a2008-06-26 23:15:51 -0300408/* image formats. */
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300409/* JPEG formats must be defined last to support jpeg_enable parameter */
Dean Anderson38f993a2008-06-26 23:15:51 -0300410static const struct s2255_fmt formats[] = {
411 {
412 .name = "4:2:2, planar, YUV422P",
413 .fourcc = V4L2_PIX_FMT_YUV422P,
414 .depth = 16
415
416 }, {
417 .name = "4:2:2, packed, YUYV",
418 .fourcc = V4L2_PIX_FMT_YUYV,
419 .depth = 16
420
421 }, {
422 .name = "4:2:2, packed, UYVY",
423 .fourcc = V4L2_PIX_FMT_UYVY,
424 .depth = 16
425 }, {
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300426 .name = "8bpp GREY",
427 .fourcc = V4L2_PIX_FMT_GREY,
428 .depth = 8
429 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300430 .name = "JPG",
431 .fourcc = V4L2_PIX_FMT_JPEG,
432 .depth = 24
433 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300434 .name = "MJPG",
435 .fourcc = V4L2_PIX_FMT_MJPEG,
436 .depth = 24
Dean Anderson38f993a2008-06-26 23:15:51 -0300437 }
438};
439
440static int norm_maxw(struct video_device *vdev)
441{
442 return (vdev->current_norm & V4L2_STD_NTSC) ?
443 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
444}
445
446static int norm_maxh(struct video_device *vdev)
447{
448 return (vdev->current_norm & V4L2_STD_NTSC) ?
449 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
450}
451
452static int norm_minw(struct video_device *vdev)
453{
454 return (vdev->current_norm & V4L2_STD_NTSC) ?
455 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
456}
457
458static int norm_minh(struct video_device *vdev)
459{
460 return (vdev->current_norm & V4L2_STD_NTSC) ?
461 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
462}
463
464
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300465/*
466 * TODO: fixme: move YUV reordering to hardware
467 * converts 2255 planar format to yuyv or uyvy
468 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300469static void planar422p_to_yuv_packed(const unsigned char *in,
470 unsigned char *out,
471 int width, int height,
472 int fmt)
473{
474 unsigned char *pY;
475 unsigned char *pCb;
476 unsigned char *pCr;
477 unsigned long size = height * width;
478 unsigned int i;
479 pY = (unsigned char *)in;
480 pCr = (unsigned char *)in + height * width;
481 pCb = (unsigned char *)in + height * width + (height * width / 2);
482 for (i = 0; i < size * 2; i += 4) {
483 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
484 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
485 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
486 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
487 }
488 return;
489}
490
Hans Verkuild45b9b82008-09-04 03:33:43 -0300491static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300492{
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300493 s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300494 msleep(10);
495 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300496 msleep(600);
497 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300498 return;
499}
Dean Anderson38f993a2008-06-26 23:15:51 -0300500
501/* kickstarts the firmware loading. from probe
502 */
503static void s2255_timer(unsigned long user_data)
504{
505 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson85b85482010-04-08 23:51:17 -0300506 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300507 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
508 printk(KERN_ERR "s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300509 atomic_set(&data->fw_state, S2255_FW_FAILED);
510 /* wake up anything waiting for the firmware */
511 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300512 return;
513 }
514}
515
Dean Anderson38f993a2008-06-26 23:15:51 -0300516
517/* this loads the firmware asynchronously.
518 Originally this was done synchroously in probe.
519 But it is better to load it asynchronously here than block
520 inside the probe function. Blocking inside probe affects boot time.
521 FW loading is triggered by the timer in the probe function
522*/
523static void s2255_fwchunk_complete(struct urb *urb)
524{
525 struct s2255_fw *data = urb->context;
526 struct usb_device *udev = urb->dev;
527 int len;
Dean Anderson85b85482010-04-08 23:51:17 -0300528 dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
Dean Anderson38f993a2008-06-26 23:15:51 -0300529 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300530 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300531 atomic_set(&data->fw_state, S2255_FW_FAILED);
532 /* wake up anything waiting for the firmware */
533 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300534 return;
535 }
536 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300537 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300538 atomic_set(&data->fw_state, S2255_FW_FAILED);
539 /* wake up anything waiting for the firmware */
540 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300541 return;
542 }
543#define CHUNK_SIZE 512
544 /* all USB transfers must be done with continuous kernel memory.
545 can't allocate more than 128k in current linux kernel, so
546 upload the firmware in chunks
547 */
548 if (data->fw_loaded < data->fw_size) {
549 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
550 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
551
552 if (len < CHUNK_SIZE)
553 memset(data->pfw_data, 0, CHUNK_SIZE);
554
555 dprintk(100, "completed len %d, loaded %d \n", len,
556 data->fw_loaded);
557
558 memcpy(data->pfw_data,
559 (char *) data->fw->data + data->fw_loaded, len);
560
561 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
562 data->pfw_data, CHUNK_SIZE,
563 s2255_fwchunk_complete, data);
564 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
565 dev_err(&udev->dev, "failed submit URB\n");
566 atomic_set(&data->fw_state, S2255_FW_FAILED);
567 /* wake up anything waiting for the firmware */
568 wake_up(&data->wait_fw);
569 return;
570 }
571 data->fw_loaded += len;
572 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300573 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson85b85482010-04-08 23:51:17 -0300574 dprintk(100, "%s: firmware upload complete\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300575 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300576 return;
577
578}
579
Dean Andersonfe85ce92010-06-01 19:12:07 -0300580static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300581{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300582 struct s2255_dmaqueue *dma_q = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300583 struct s2255_buffer *buf;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300584 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300585 unsigned long flags = 0;
586 int rc = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300587 spin_lock_irqsave(&dev->slock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300588 if (list_empty(&dma_q->active)) {
589 dprintk(1, "No active queue to serve\n");
590 rc = -1;
591 goto unlock;
592 }
593 buf = list_entry(dma_q->active.next,
594 struct s2255_buffer, vb.queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300595 list_del(&buf->vb.queue);
Sakari Ailus8e6057b2012-09-15 15:14:42 -0300596 v4l2_get_timestamp(&buf->vb.ts);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300597 s2255_fillbuff(channel, buf, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300598 wake_up(&buf->vb.done);
Dean Anderson85b85482010-04-08 23:51:17 -0300599 dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
Dean Anderson38f993a2008-06-26 23:15:51 -0300600unlock:
601 spin_unlock_irqrestore(&dev->slock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300602 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300603}
604
Dean Anderson38f993a2008-06-26 23:15:51 -0300605static const struct s2255_fmt *format_by_fourcc(int fourcc)
606{
607 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300608 for (i = 0; i < ARRAY_SIZE(formats); i++) {
609 if (-1 == formats[i].fourcc)
610 continue;
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300611 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
612 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
613 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300614 if (formats[i].fourcc == fourcc)
615 return formats + i;
616 }
617 return NULL;
618}
619
Dean Anderson38f993a2008-06-26 23:15:51 -0300620/* video buffer vmalloc implementation based partly on VIVI driver which is
621 * Copyright (c) 2006 by
622 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
623 * Ted Walther <ted--a.t--enumera.com>
624 * John Sokol <sokol--a.t--videotechnology.com>
625 * http://v4l.videotechnology.com/
626 *
627 */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300628static void s2255_fillbuff(struct s2255_channel *channel,
629 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300630{
631 int pos = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300632 const char *tmpbuf;
633 char *vbuf = videobuf_to_vmalloc(&buf->vb);
634 unsigned long last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300635
636 if (!vbuf)
637 return;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300638 last_frame = channel->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300639 if (last_frame != -1) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300640 tmpbuf =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300641 (const char *)channel->buffer.frame[last_frame].lpvbits;
Dean Anderson38f993a2008-06-26 23:15:51 -0300642 switch (buf->fmt->fourcc) {
643 case V4L2_PIX_FMT_YUYV:
644 case V4L2_PIX_FMT_UYVY:
645 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
646 vbuf, buf->vb.width,
647 buf->vb.height,
648 buf->fmt->fourcc);
649 break;
650 case V4L2_PIX_FMT_GREY:
651 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
652 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300653 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300654 case V4L2_PIX_FMT_MJPEG:
Dean Anderson14d96262008-08-25 13:58:55 -0300655 buf->vb.size = jpgsize;
656 memcpy(vbuf, tmpbuf, buf->vb.size);
657 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300658 case V4L2_PIX_FMT_YUV422P:
659 memcpy(vbuf, tmpbuf,
660 buf->vb.width * buf->vb.height * 2);
661 break;
662 default:
663 printk(KERN_DEBUG "s2255: unknown format?\n");
664 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300665 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300666 } else {
667 printk(KERN_ERR "s2255: =======no frame\n");
668 return;
669
670 }
671 dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
672 (unsigned long)vbuf, pos);
673 /* tell v4l buffer was filled */
674
Dean Andersonfe85ce92010-06-01 19:12:07 -0300675 buf->vb.field_count = channel->frame_count * 2;
Sakari Ailus8e6057b2012-09-15 15:14:42 -0300676 v4l2_get_timestamp(&buf->vb.ts);
Dean Anderson38f993a2008-06-26 23:15:51 -0300677 buf->vb.state = VIDEOBUF_DONE;
678}
679
680
681/* ------------------------------------------------------------------
682 Videobuf operations
683 ------------------------------------------------------------------*/
684
685static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
686 unsigned int *size)
687{
688 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300689 struct s2255_channel *channel = fh->channel;
690 *size = channel->width * channel->height * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300691
692 if (0 == *count)
693 *count = S2255_DEF_BUFS;
694
Andreas Bombedab7e312010-03-21 16:02:45 -0300695 if (*size * *count > vid_limit * 1024 * 1024)
696 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300697
698 return 0;
699}
700
701static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
702{
703 dprintk(4, "%s\n", __func__);
704
Dean Anderson38f993a2008-06-26 23:15:51 -0300705 videobuf_vmalloc_free(&buf->vb);
706 buf->vb.state = VIDEOBUF_NEEDS_INIT;
707}
708
709static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
710 enum v4l2_field field)
711{
712 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300713 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300714 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
715 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300716 int w = channel->width;
717 int h = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300718 dprintk(4, "%s, field=%d\n", __func__, field);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300719 if (channel->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300720 return -EINVAL;
721
Dean Andersonfe85ce92010-06-01 19:12:07 -0300722 if ((w < norm_minw(&channel->vdev)) ||
723 (w > norm_maxw(&channel->vdev)) ||
724 (h < norm_minh(&channel->vdev)) ||
725 (h > norm_maxh(&channel->vdev))) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300726 dprintk(4, "invalid buffer prepare\n");
727 return -EINVAL;
728 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300729 buf->vb.size = w * h * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300730 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
731 dprintk(4, "invalid buffer prepare\n");
732 return -EINVAL;
733 }
734
Dean Andersonfe85ce92010-06-01 19:12:07 -0300735 buf->fmt = channel->fmt;
736 buf->vb.width = w;
737 buf->vb.height = h;
Dean Anderson38f993a2008-06-26 23:15:51 -0300738 buf->vb.field = field;
739
Dean Anderson38f993a2008-06-26 23:15:51 -0300740 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
741 rc = videobuf_iolock(vq, &buf->vb, NULL);
742 if (rc < 0)
743 goto fail;
744 }
745
746 buf->vb.state = VIDEOBUF_PREPARED;
747 return 0;
748fail:
749 free_buffer(vq, buf);
750 return rc;
751}
752
753static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
754{
755 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
756 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300757 struct s2255_channel *channel = fh->channel;
758 struct s2255_dmaqueue *vidq = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300759 dprintk(1, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300760 buf->vb.state = VIDEOBUF_QUEUED;
761 list_add_tail(&buf->vb.queue, &vidq->active);
762}
763
764static void buffer_release(struct videobuf_queue *vq,
765 struct videobuf_buffer *vb)
766{
767 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
768 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300769 dprintk(4, "%s %d\n", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -0300770 free_buffer(vq, buf);
771}
772
773static struct videobuf_queue_ops s2255_video_qops = {
774 .buf_setup = buffer_setup,
775 .buf_prepare = buffer_prepare,
776 .buf_queue = buffer_queue,
777 .buf_release = buffer_release,
778};
779
780
Dean Andersonfe85ce92010-06-01 19:12:07 -0300781static int res_get(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300782{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300783 struct s2255_channel *channel = fh->channel;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300784 /* is it free? */
785 if (channel->resources)
786 return 0; /* no, someone else uses it */
Dean Anderson38f993a2008-06-26 23:15:51 -0300787 /* it's free, grab it */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300788 channel->resources = 1;
789 fh->resources = 1;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300790 dprintk(1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300791 return 1;
792}
793
Dean Andersonfe85ce92010-06-01 19:12:07 -0300794static int res_locked(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300795{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300796 return fh->channel->resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300797}
798
Dean Andersonf78d92c2008-07-22 14:43:27 -0300799static int res_check(struct s2255_fh *fh)
800{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300801 return fh->resources;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300802}
803
804
Dean Andersonfe85ce92010-06-01 19:12:07 -0300805static void res_free(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300806{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300807 struct s2255_channel *channel = fh->channel;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300808 channel->resources = 0;
809 fh->resources = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300810 dprintk(1, "res: put\n");
811}
812
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300813static int vidioc_querymenu(struct file *file, void *priv,
814 struct v4l2_querymenu *qmenu)
815{
816 static const char *colorfilter[] = {
817 "Off",
818 "On",
819 NULL
820 };
821 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
822 int i;
823 const char **menu_items = colorfilter;
824 for (i = 0; i < qmenu->index && menu_items[i]; i++)
825 ; /* do nothing (from v4l2-common.c) */
826 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
827 return -EINVAL;
828 strlcpy(qmenu->name, menu_items[qmenu->index],
829 sizeof(qmenu->name));
830 return 0;
831 }
832 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
833}
834
Dean Anderson38f993a2008-06-26 23:15:51 -0300835static int vidioc_querycap(struct file *file, void *priv,
836 struct v4l2_capability *cap)
837{
838 struct s2255_fh *fh = file->private_data;
839 struct s2255_dev *dev = fh->dev;
840 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
841 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300842 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Dean Anderson38f993a2008-06-26 23:15:51 -0300843 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
844 return 0;
845}
846
847static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
848 struct v4l2_fmtdesc *f)
849{
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300850 int index = f->index;
Dean Anderson38f993a2008-06-26 23:15:51 -0300851
852 if (index >= ARRAY_SIZE(formats))
853 return -EINVAL;
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300854 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
855 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
856 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300857 dprintk(4, "name %s\n", formats[index].name);
858 strlcpy(f->description, formats[index].name, sizeof(f->description));
859 f->pixelformat = formats[index].fourcc;
860 return 0;
861}
862
863static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
864 struct v4l2_format *f)
865{
866 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300867 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300868
Dean Andersonfe85ce92010-06-01 19:12:07 -0300869 f->fmt.pix.width = channel->width;
870 f->fmt.pix.height = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300871 f->fmt.pix.field = fh->vb_vidq.field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300872 f->fmt.pix.pixelformat = channel->fmt->fourcc;
873 f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300874 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300875 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300876}
877
878static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
879 struct v4l2_format *f)
880{
881 const struct s2255_fmt *fmt;
882 enum v4l2_field field;
883 int b_any_field = 0;
884 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300885 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300886 int is_ntsc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300887 is_ntsc =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300888 (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300889
890 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
891
892 if (fmt == NULL)
893 return -EINVAL;
894
895 field = f->fmt.pix.field;
896 if (field == V4L2_FIELD_ANY)
897 b_any_field = 1;
898
Dean Anderson85b85482010-04-08 23:51:17 -0300899 dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
900 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300901 if (is_ntsc) {
902 /* NTSC */
903 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
904 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
905 if (b_any_field) {
906 field = V4L2_FIELD_SEQ_TB;
907 } else if (!((field == V4L2_FIELD_INTERLACED) ||
908 (field == V4L2_FIELD_SEQ_TB) ||
909 (field == V4L2_FIELD_INTERLACED_TB))) {
910 dprintk(1, "unsupported field setting\n");
911 return -EINVAL;
912 }
913 } else {
914 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
915 if (b_any_field) {
916 field = V4L2_FIELD_TOP;
917 } else if (!((field == V4L2_FIELD_TOP) ||
918 (field == V4L2_FIELD_BOTTOM))) {
919 dprintk(1, "unsupported field setting\n");
920 return -EINVAL;
921 }
922
923 }
924 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
925 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
926 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
927 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
928 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
929 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
930 else
931 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
932 } else {
933 /* PAL */
934 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
935 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
936 if (b_any_field) {
937 field = V4L2_FIELD_SEQ_TB;
938 } else if (!((field == V4L2_FIELD_INTERLACED) ||
939 (field == V4L2_FIELD_SEQ_TB) ||
940 (field == V4L2_FIELD_INTERLACED_TB))) {
941 dprintk(1, "unsupported field setting\n");
942 return -EINVAL;
943 }
944 } else {
945 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
946 if (b_any_field) {
947 field = V4L2_FIELD_TOP;
948 } else if (!((field == V4L2_FIELD_TOP) ||
949 (field == V4L2_FIELD_BOTTOM))) {
950 dprintk(1, "unsupported field setting\n");
951 return -EINVAL;
952 }
953 }
954 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300955 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
956 field = V4L2_FIELD_SEQ_TB;
957 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300958 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
959 field = V4L2_FIELD_TOP;
960 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300961 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
962 field = V4L2_FIELD_TOP;
963 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300964 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
965 field = V4L2_FIELD_TOP;
966 }
967 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300968 f->fmt.pix.field = field;
969 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
970 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson85b85482010-04-08 23:51:17 -0300971 dprintk(50, "%s: set width %d height %d field %d\n", __func__,
972 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300973 return 0;
974}
975
976static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
977 struct v4l2_format *f)
978{
979 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300980 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300981 const struct s2255_fmt *fmt;
982 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300983 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300984 int ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300985
986 ret = vidioc_try_fmt_vid_cap(file, fh, f);
987
988 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300989 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300990
991 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
992
993 if (fmt == NULL)
994 return -EINVAL;
995
996 mutex_lock(&q->vb_lock);
997
998 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
999 dprintk(1, "queue busy\n");
1000 ret = -EBUSY;
1001 goto out_s_fmt;
1002 }
1003
Dean Andersonfe85ce92010-06-01 19:12:07 -03001004 if (res_locked(fh)) {
Dean Anderson85b85482010-04-08 23:51:17 -03001005 dprintk(1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001006 ret = -EBUSY;
1007 goto out_s_fmt;
1008 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001009 mode = channel->mode;
1010 channel->fmt = fmt;
1011 channel->width = f->fmt.pix.width;
1012 channel->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -03001013 fh->vb_vidq.field = f->fmt.pix.field;
1014 fh->type = f->type;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001015 if (channel->width > norm_minw(&channel->vdev)) {
1016 if (channel->height > norm_minh(&channel->vdev)) {
1017 if (channel->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -03001018 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001019 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -03001020 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001021 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -03001022 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001023 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001024
1025 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001026 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001027 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001028 /* color mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001029 switch (channel->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001030 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001031 mode.color &= ~MASK_COLOR;
1032 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001033 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001034 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -03001035 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001036 mode.color &= ~MASK_COLOR;
1037 mode.color |= COLOR_JPG;
1038 mode.color |= (channel->jc.quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001039 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001040 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001041 mode.color &= ~MASK_COLOR;
1042 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001043 break;
1044 case V4L2_PIX_FMT_YUYV:
1045 case V4L2_PIX_FMT_UYVY:
1046 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001047 mode.color &= ~MASK_COLOR;
1048 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001049 break;
1050 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001051 if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
1052 mode.restart = 1;
1053 else if (mode.scale != channel->mode.scale)
1054 mode.restart = 1;
1055 else if (mode.format != channel->mode.format)
1056 mode.restart = 1;
1057 channel->mode = mode;
1058 (void) s2255_set_mode(channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001059 ret = 0;
1060out_s_fmt:
1061 mutex_unlock(&q->vb_lock);
1062 return ret;
1063}
1064
1065static int vidioc_reqbufs(struct file *file, void *priv,
1066 struct v4l2_requestbuffers *p)
1067{
1068 int rc;
1069 struct s2255_fh *fh = priv;
1070 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1071 return rc;
1072}
1073
1074static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1075{
1076 int rc;
1077 struct s2255_fh *fh = priv;
1078 rc = videobuf_querybuf(&fh->vb_vidq, p);
1079 return rc;
1080}
1081
1082static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1083{
1084 int rc;
1085 struct s2255_fh *fh = priv;
1086 rc = videobuf_qbuf(&fh->vb_vidq, p);
1087 return rc;
1088}
1089
1090static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1091{
1092 int rc;
1093 struct s2255_fh *fh = priv;
1094 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1095 return rc;
1096}
1097
Dean Anderson38f993a2008-06-26 23:15:51 -03001098/* write to the configuration pipe, synchronously */
1099static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1100 int size)
1101{
1102 int pipe;
1103 int done;
1104 long retval = -1;
1105 if (udev) {
1106 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1107 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1108 }
1109 return retval;
1110}
1111
1112static u32 get_transfer_size(struct s2255_mode *mode)
1113{
1114 int linesPerFrame = LINE_SZ_DEF;
1115 int pixelsPerLine = NUM_LINES_DEF;
1116 u32 outImageSize;
1117 u32 usbInSize;
1118 unsigned int mask_mult;
1119
1120 if (mode == NULL)
1121 return 0;
1122
1123 if (mode->format == FORMAT_NTSC) {
1124 switch (mode->scale) {
1125 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001126 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001127 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1128 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1129 break;
1130 case SCALE_2CIFS:
1131 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1132 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1133 break;
1134 case SCALE_1CIFS:
1135 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1136 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1137 break;
1138 default:
1139 break;
1140 }
1141 } else if (mode->format == FORMAT_PAL) {
1142 switch (mode->scale) {
1143 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001144 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001145 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1146 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1147 break;
1148 case SCALE_2CIFS:
1149 linesPerFrame = NUM_LINES_2CIFS_PAL;
1150 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1151 break;
1152 case SCALE_1CIFS:
1153 linesPerFrame = NUM_LINES_1CIFS_PAL;
1154 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1155 break;
1156 default:
1157 break;
1158 }
1159 }
1160 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001161 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001162 /* 2 bytes/pixel if not monochrome */
1163 outImageSize *= 2;
1164 }
1165
1166 /* total bytes to send including prefix and 4K padding;
1167 must be a multiple of USB_READ_SIZE */
1168 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1169 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1170 /* if size not a multiple of USB_READ_SIZE */
1171 if (usbInSize & ~mask_mult)
1172 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1173 return usbInSize;
1174}
1175
Dean Anderson85b85482010-04-08 23:51:17 -03001176static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001177{
1178 struct device *dev = &sdev->udev->dev;
1179 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001180 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1181 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001182 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001183 dev_info(dev, "------------------------------------------------\n");
1184}
1185
1186/*
1187 * set mode is the function which controls the DSP.
1188 * the restart parameter in struct s2255_mode should be set whenever
1189 * the image size could change via color format, video system or image
1190 * size.
1191 * When the restart parameter is set, we sleep for ONE frame to allow the
1192 * DSP time to get the new frame
1193 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001194static int s2255_set_mode(struct s2255_channel *channel,
Dean Anderson38f993a2008-06-26 23:15:51 -03001195 struct s2255_mode *mode)
1196{
1197 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001198 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001199 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001200 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001201 chn_rev = G_chnmap[channel->idx];
1202 dprintk(3, "%s channel: %d\n", __func__, channel->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001203 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001204 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1205 mode->color &= ~MASK_COLOR;
1206 mode->color |= COLOR_JPG;
1207 mode->color &= ~MASK_JPG_QUALITY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001208 mode->color |= (channel->jc.quality << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001209 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001210 /* save the mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001211 channel->mode = *mode;
1212 channel->req_image_size = get_transfer_size(mode);
1213 dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001214 buffer = kzalloc(512, GFP_KERNEL);
1215 if (buffer == NULL) {
1216 dev_err(&dev->udev->dev, "out of mem\n");
1217 return -ENOMEM;
1218 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001219 /* set the mode */
1220 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001221 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001222 buffer[2] = CMD_SET_MODE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001223 memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
1224 channel->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001225 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1226 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001227 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001228 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001229 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001230 if (mode->restart) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001231 wait_event_timeout(channel->wait_setmode,
1232 (channel->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001233 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001234 if (channel->setmode_ready != 1) {
Dean Anderson14d96262008-08-25 13:58:55 -03001235 printk(KERN_DEBUG "s2255: no set mode response\n");
1236 res = -EFAULT;
1237 }
1238 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001239 /* clear the restart flag */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001240 channel->mode.restart = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001241 dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001242 return res;
1243}
1244
Dean Andersonfe85ce92010-06-01 19:12:07 -03001245static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001246{
1247 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001248 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001249 u32 chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001250 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001251 chn_rev = G_chnmap[channel->idx];
1252 dprintk(4, "%s chan %d\n", __func__, channel->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001253 buffer = kzalloc(512, GFP_KERNEL);
1254 if (buffer == NULL) {
1255 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001256 return -ENOMEM;
1257 }
1258 /* form the get vid status command */
1259 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001260 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001261 buffer[2] = CMD_STATUS;
1262 *pstatus = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001263 channel->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001264 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1265 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001266 wait_event_timeout(channel->wait_vidstatus,
1267 (channel->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001268 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001269 if (channel->vidstatus_ready != 1) {
Dean Anderson4de39f52010-03-03 19:39:19 -03001270 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1271 res = -EFAULT;
1272 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001273 *pstatus = channel->vidstatus;
Dean Anderson4de39f52010-03-03 19:39:19 -03001274 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03001275 return res;
1276}
1277
Dean Anderson38f993a2008-06-26 23:15:51 -03001278static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1279{
1280 int res;
1281 struct s2255_fh *fh = priv;
1282 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001283 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001284 int j;
1285 dprintk(4, "%s\n", __func__);
1286 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1287 dev_err(&dev->udev->dev, "invalid fh type0\n");
1288 return -EINVAL;
1289 }
1290 if (i != fh->type) {
1291 dev_err(&dev->udev->dev, "invalid fh type1\n");
1292 return -EINVAL;
1293 }
1294
Dean Andersonfe85ce92010-06-01 19:12:07 -03001295 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001296 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001297 return -EBUSY;
1298 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001299 channel->last_frame = -1;
1300 channel->bad_payload = 0;
1301 channel->cur_frame = 0;
1302 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001303 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001304 channel->buffer.frame[j].ulState = S2255_READ_IDLE;
1305 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001306 }
1307 res = videobuf_streamon(&fh->vb_vidq);
1308 if (res == 0) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001309 s2255_start_acquire(channel);
1310 channel->b_acquire = 1;
1311 } else
1312 res_free(fh);
1313
Dean Anderson38f993a2008-06-26 23:15:51 -03001314 return res;
1315}
1316
1317static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1318{
Dean Anderson38f993a2008-06-26 23:15:51 -03001319 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001320 dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001321 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1322 printk(KERN_ERR "invalid fh type0\n");
1323 return -EINVAL;
1324 }
1325 if (i != fh->type) {
1326 printk(KERN_ERR "invalid type i\n");
1327 return -EINVAL;
1328 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001329 s2255_stop_acquire(fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001330 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001331 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001332 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001333}
1334
1335static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1336{
1337 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001338 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001339 struct videobuf_queue *q = &fh->vb_vidq;
1340 int ret = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001341 mutex_lock(&q->vb_lock);
1342 if (videobuf_queue_is_busy(q)) {
1343 dprintk(1, "queue busy\n");
1344 ret = -EBUSY;
1345 goto out_s_std;
1346 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001347 if (res_locked(fh)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001348 dprintk(1, "can't change standard after started\n");
1349 ret = -EBUSY;
1350 goto out_s_std;
1351 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001352 mode = fh->channel->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001353 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001354 dprintk(4, "%s NTSC\n", __func__);
1355 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001356 if (mode.format != FORMAT_NTSC) {
1357 mode.restart = 1;
1358 mode.format = FORMAT_NTSC;
1359 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001360 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001361 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001362 dprintk(4, "%s PAL\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001363 if (mode.format != FORMAT_PAL) {
1364 mode.restart = 1;
1365 mode.format = FORMAT_PAL;
1366 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001367 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001368 } else {
1369 ret = -EINVAL;
1370 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001371 if (mode.restart)
1372 s2255_set_mode(fh->channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001373out_s_std:
1374 mutex_unlock(&q->vb_lock);
1375 return ret;
1376}
1377
1378/* Sensoray 2255 is a multiple channel capture device.
1379 It does not have a "crossbar" of inputs.
1380 We use one V4L device per channel. The user must
1381 be aware that certain combinations are not allowed.
1382 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1383 at once in color(you can do full fps on 4 channels with greyscale.
1384*/
1385static int vidioc_enum_input(struct file *file, void *priv,
1386 struct v4l2_input *inp)
1387{
Dean Anderson4de39f52010-03-03 19:39:19 -03001388 struct s2255_fh *fh = priv;
1389 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001390 struct s2255_channel *channel = fh->channel;
Dean Anderson4de39f52010-03-03 19:39:19 -03001391 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001392 if (inp->index != 0)
1393 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001394 inp->type = V4L2_INPUT_TYPE_CAMERA;
1395 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001396 inp->status = 0;
1397 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1398 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001399 rc = s2255_cmd_status(fh->channel, &status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001400 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1401 if (rc == 0)
1402 inp->status = (status & 0x01) ? 0
1403 : V4L2_IN_ST_NO_SIGNAL;
1404 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001405 switch (dev->pid) {
1406 case 0x2255:
1407 default:
1408 strlcpy(inp->name, "Composite", sizeof(inp->name));
1409 break;
1410 case 0x2257:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001411 strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001412 sizeof(inp->name));
1413 break;
1414 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001415 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001416}
1417
1418static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1419{
1420 *i = 0;
1421 return 0;
1422}
1423static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1424{
1425 if (i > 0)
1426 return -EINVAL;
1427 return 0;
1428}
1429
1430/* --- controls ---------------------------------------------- */
1431static int vidioc_queryctrl(struct file *file, void *priv,
1432 struct v4l2_queryctrl *qc)
1433{
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001434 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001435 struct s2255_channel *channel = fh->channel;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001436 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001437 switch (qc->id) {
1438 case V4L2_CID_BRIGHTNESS:
1439 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1440 break;
1441 case V4L2_CID_CONTRAST:
1442 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1443 break;
1444 case V4L2_CID_SATURATION:
1445 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1446 break;
1447 case V4L2_CID_HUE:
1448 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1449 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001450 case V4L2_CID_PRIVATE_COLORFILTER:
1451 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1452 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001453 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001454 return -EINVAL;
1455 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1456 qc->type = V4L2_CTRL_TYPE_MENU;
1457 qc->minimum = 0;
1458 qc->maximum = 1;
1459 qc->step = 1;
1460 qc->default_value = 1;
1461 qc->flags = 0;
1462 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001463 default:
1464 return -EINVAL;
1465 }
1466 dprintk(4, "%s, id %d\n", __func__, qc->id);
1467 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001468}
1469
1470static int vidioc_g_ctrl(struct file *file, void *priv,
1471 struct v4l2_control *ctrl)
1472{
Dean Anderson2e70db92010-03-05 14:29:09 -03001473 struct s2255_fh *fh = priv;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001474 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001475 struct s2255_channel *channel = fh->channel;
Dean Anderson2e70db92010-03-05 14:29:09 -03001476 switch (ctrl->id) {
1477 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001478 ctrl->value = channel->mode.bright;
Dean Anderson2e70db92010-03-05 14:29:09 -03001479 break;
1480 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001481 ctrl->value = channel->mode.contrast;
Dean Anderson2e70db92010-03-05 14:29:09 -03001482 break;
1483 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001484 ctrl->value = channel->mode.saturation;
Dean Anderson2e70db92010-03-05 14:29:09 -03001485 break;
1486 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001487 ctrl->value = channel->mode.hue;
Dean Anderson2e70db92010-03-05 14:29:09 -03001488 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001489 case V4L2_CID_PRIVATE_COLORFILTER:
1490 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1491 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001492 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001493 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001494 ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001495 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001496 default:
1497 return -EINVAL;
1498 }
1499 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1500 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001501}
1502
1503static int vidioc_s_ctrl(struct file *file, void *priv,
1504 struct v4l2_control *ctrl)
1505{
Dean Anderson38f993a2008-06-26 23:15:51 -03001506 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001507 struct s2255_channel *channel = fh->channel;
1508 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
1509 struct s2255_mode mode;
1510 mode = channel->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001511 dprintk(4, "%s\n", __func__);
1512 /* update the mode to the corresponding value */
1513 switch (ctrl->id) {
1514 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001515 mode.bright = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001516 break;
1517 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001518 mode.contrast = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001519 break;
1520 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001521 mode.hue = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001522 break;
1523 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001524 mode.saturation = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001525 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001526 case V4L2_CID_PRIVATE_COLORFILTER:
1527 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1528 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001529 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001530 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001531 mode.color &= ~MASK_INPUT_TYPE;
1532 mode.color |= ((ctrl->value ? 0 : 1) << 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001533 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001534 default:
1535 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001536 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001537 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001538 /* set mode here. Note: stream does not need restarted.
1539 some V4L programs restart stream unnecessarily
1540 after a s_crtl.
1541 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001542 s2255_set_mode(fh->channel, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001543 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001544}
1545
Dean Anderson22b88d42008-08-29 15:33:19 -03001546static int vidioc_g_jpegcomp(struct file *file, void *priv,
1547 struct v4l2_jpegcompression *jc)
1548{
1549 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001550 struct s2255_channel *channel = fh->channel;
1551 *jc = channel->jc;
Dean Anderson85b85482010-04-08 23:51:17 -03001552 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001553 return 0;
1554}
1555
1556static int vidioc_s_jpegcomp(struct file *file, void *priv,
Hans Verkuild88aab52012-09-17 05:05:25 -03001557 const struct v4l2_jpegcompression *jc)
Dean Anderson22b88d42008-08-29 15:33:19 -03001558{
1559 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001560 struct s2255_channel *channel = fh->channel;
Dean Anderson22b88d42008-08-29 15:33:19 -03001561 if (jc->quality < 0 || jc->quality > 100)
1562 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001563 channel->jc.quality = jc->quality;
Dean Anderson85b85482010-04-08 23:51:17 -03001564 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001565 return 0;
1566}
Dean Anderson7d853532009-05-15 14:32:04 -03001567
1568static int vidioc_g_parm(struct file *file, void *priv,
1569 struct v4l2_streamparm *sp)
1570{
1571 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001572 __u32 def_num, def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001573 struct s2255_channel *channel = fh->channel;
Dean Anderson7d853532009-05-15 14:32:04 -03001574 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1575 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001576 memset(sp, 0, sizeof(struct v4l2_streamparm));
1577 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001578 sp->parm.capture.capturemode = channel->cap_parm.capturemode;
1579 def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1580 def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001581 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001582 switch (channel->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001583 default:
1584 case FDEC_1:
1585 sp->parm.capture.timeperframe.numerator = def_num;
1586 break;
1587 case FDEC_2:
1588 sp->parm.capture.timeperframe.numerator = def_num * 2;
1589 break;
1590 case FDEC_3:
1591 sp->parm.capture.timeperframe.numerator = def_num * 3;
1592 break;
1593 case FDEC_5:
1594 sp->parm.capture.timeperframe.numerator = def_num * 5;
1595 break;
1596 }
1597 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1598 sp->parm.capture.capturemode,
1599 sp->parm.capture.timeperframe.numerator,
1600 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001601 return 0;
1602}
1603
1604static int vidioc_s_parm(struct file *file, void *priv,
1605 struct v4l2_streamparm *sp)
1606{
1607 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001608 struct s2255_channel *channel = fh->channel;
1609 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001610 int fdec = FDEC_1;
1611 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001612 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1613 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001614 mode = channel->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001615 /* high quality capture mode requires a stream restart */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001616 if (channel->cap_parm.capturemode
1617 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001618 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001619 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1620 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001621 if (def_dem != sp->parm.capture.timeperframe.denominator)
1622 sp->parm.capture.timeperframe.numerator = def_num;
1623 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1624 sp->parm.capture.timeperframe.numerator = def_num;
1625 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1626 sp->parm.capture.timeperframe.numerator = def_num * 2;
1627 fdec = FDEC_2;
1628 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1629 sp->parm.capture.timeperframe.numerator = def_num * 3;
1630 fdec = FDEC_3;
1631 } else {
1632 sp->parm.capture.timeperframe.numerator = def_num * 5;
1633 fdec = FDEC_5;
1634 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001635 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001636 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001637 s2255_set_mode(channel, &mode);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001638 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1639 __func__,
1640 sp->parm.capture.capturemode,
1641 sp->parm.capture.timeperframe.numerator,
1642 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001643 return 0;
1644}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001645
1646static int vidioc_enum_frameintervals(struct file *file, void *priv,
1647 struct v4l2_frmivalenum *fe)
1648{
1649 int is_ntsc = 0;
1650#define NUM_FRAME_ENUMS 4
1651 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
Mauro Carvalho Chehab199ab8f2012-10-27 16:29:34 -03001652 if (fe->index >= NUM_FRAME_ENUMS)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001653 return -EINVAL;
1654 switch (fe->width) {
1655 case 640:
1656 if (fe->height != 240 && fe->height != 480)
1657 return -EINVAL;
1658 is_ntsc = 1;
1659 break;
1660 case 320:
1661 if (fe->height != 240)
1662 return -EINVAL;
1663 is_ntsc = 1;
1664 break;
1665 case 704:
1666 if (fe->height != 288 && fe->height != 576)
1667 return -EINVAL;
1668 break;
1669 case 352:
1670 if (fe->height != 288)
1671 return -EINVAL;
1672 break;
1673 default:
1674 return -EINVAL;
1675 }
1676 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1677 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1678 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1679 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1680 fe->discrete.denominator);
1681 return 0;
1682}
1683
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001684static int __s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001685{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001686 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001687 struct s2255_channel *channel = video_drvdata(file);
1688 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001689 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001690 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001691 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001692 dprintk(1, "s2255: open called (dev=%s)\n",
1693 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001694 state = atomic_read(&dev->fw_data->fw_state);
1695 switch (state) {
1696 case S2255_FW_DISCONNECTING:
Dean Andersonff7e22d2010-04-08 23:38:07 -03001697 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001698 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001699 s2255_dev_err(&dev->udev->dev,
1700 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001701 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001702 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001703 ((atomic_read(&dev->fw_data->fw_state)
1704 == S2255_FW_SUCCESS) ||
1705 (atomic_read(&dev->fw_data->fw_state)
1706 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001707 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001708 /* state may have changed, re-read */
1709 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001710 break;
1711 case S2255_FW_NOTLOADED:
1712 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001713 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1714 driver loaded and then device immediately opened */
1715 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1716 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001717 ((atomic_read(&dev->fw_data->fw_state)
1718 == S2255_FW_SUCCESS) ||
1719 (atomic_read(&dev->fw_data->fw_state)
1720 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001721 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001722 /* state may have changed, re-read */
1723 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001724 break;
1725 case S2255_FW_SUCCESS:
1726 default:
1727 break;
1728 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001729 /* state may have changed in above switch statement */
1730 switch (state) {
1731 case S2255_FW_SUCCESS:
1732 break;
1733 case S2255_FW_FAILED:
1734 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03001735 return -ENODEV;
1736 case S2255_FW_DISCONNECTING:
1737 printk(KERN_INFO "%s: disconnecting\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001738 return -ENODEV;
1739 case S2255_FW_LOADED_DSPWAIT:
1740 case S2255_FW_NOTLOADED:
1741 printk(KERN_INFO "%s: firmware not loaded yet"
1742 "please try again later\n",
1743 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001744 /*
1745 * Timeout on firmware load means device unusable.
1746 * Set firmware failure state.
1747 * On next s2255_open the firmware will be reloaded.
1748 */
1749 atomic_set(&dev->fw_data->fw_state,
1750 S2255_FW_FAILED);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001751 return -EAGAIN;
1752 default:
1753 printk(KERN_INFO "%s: unknown state\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001754 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001755 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001756 /* allocate + initialize per filehandle data */
1757 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001758 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001759 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03001760 file->private_data = fh;
1761 fh->dev = dev;
1762 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001763 fh->channel = channel;
1764 if (!channel->configured) {
1765 /* configure channel to default state */
1766 channel->fmt = &formats[0];
1767 s2255_set_mode(channel, &channel->mode);
1768 channel->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001769 }
Dean Anderson85b85482010-04-08 23:51:17 -03001770 dprintk(1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001771 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson85b85482010-04-08 23:51:17 -03001772 dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001773 (unsigned long)fh, (unsigned long)dev,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001774 (unsigned long)&channel->vidq);
Dean Anderson85b85482010-04-08 23:51:17 -03001775 dprintk(4, "%s: list_empty active=%d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001776 list_empty(&channel->vidq.active));
Dean Anderson38f993a2008-06-26 23:15:51 -03001777 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1778 NULL, &dev->slock,
1779 fh->type,
1780 V4L2_FIELD_INTERLACED,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001781 sizeof(struct s2255_buffer),
1782 fh, vdev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001783 return 0;
1784}
1785
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001786static int s2255_open(struct file *file)
1787{
1788 struct video_device *vdev = video_devdata(file);
1789 int ret;
1790
1791 if (mutex_lock_interruptible(vdev->lock))
1792 return -ERESTARTSYS;
1793 ret = __s2255_open(file);
1794 mutex_unlock(vdev->lock);
1795 return ret;
1796}
Dean Anderson38f993a2008-06-26 23:15:51 -03001797
1798static unsigned int s2255_poll(struct file *file,
1799 struct poll_table_struct *wait)
1800{
1801 struct s2255_fh *fh = file->private_data;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001802 struct s2255_dev *dev = fh->dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001803 int rc;
1804 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001805 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1806 return POLLERR;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001807 mutex_lock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001808 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001809 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001810 return rc;
1811}
1812
Dean Andersond62e85a2010-04-09 19:54:26 -03001813static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001814{
Dean Anderson38f993a2008-06-26 23:15:51 -03001815 /* board shutdown stops the read pipe if it is running */
1816 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001817 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001818 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001819 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001820 usb_kill_urb(dev->fw_data->fw_urb);
1821 usb_free_urb(dev->fw_data->fw_urb);
1822 dev->fw_data->fw_urb = NULL;
1823 }
Jesper Juhl3fc82fa2012-04-09 16:50:04 -03001824 release_firmware(dev->fw_data->fw);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001825 kfree(dev->fw_data->pfw_data);
1826 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001827 /* reset the DSP so firmware can be reloaded next time */
1828 s2255_reset_dsppower(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001829 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001830 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001831 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001832 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001833 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001834}
1835
Dean Andersonff7e22d2010-04-08 23:38:07 -03001836static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001837{
1838 struct s2255_fh *fh = file->private_data;
1839 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001840 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001841 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001842 if (!dev)
1843 return -ENODEV;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001844 mutex_lock(&dev->lock);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001845 /* turn off stream */
1846 if (res_check(fh)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001847 if (channel->b_acquire)
1848 s2255_stop_acquire(fh->channel);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001849 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001850 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001851 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001852 videobuf_mmap_free(&fh->vb_vidq);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001853 mutex_unlock(&dev->lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001854 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001855 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001856 return 0;
1857}
1858
1859static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1860{
1861 struct s2255_fh *fh = file->private_data;
Julia Lawalle8397762012-08-14 11:49:46 -03001862 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001863 int ret;
1864
1865 if (!fh)
1866 return -ENODEV;
Julia Lawalle8397762012-08-14 11:49:46 -03001867 dev = fh->dev;
Dean Anderson85b85482010-04-08 23:51:17 -03001868 dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001869 if (mutex_lock_interruptible(&dev->lock))
1870 return -ERESTARTSYS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001871 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001872 mutex_unlock(&dev->lock);
Dean Anderson85b85482010-04-08 23:51:17 -03001873 dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001874 (unsigned long)vma->vm_start,
1875 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001876 return ret;
1877}
1878
Hans Verkuilbec43662008-12-30 06:58:20 -03001879static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001880 .owner = THIS_MODULE,
1881 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001882 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001883 .poll = s2255_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001884 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001885 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001886};
1887
Hans Verkuila3998102008-07-21 02:57:38 -03001888static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001889 .vidioc_querymenu = vidioc_querymenu,
Dean Anderson38f993a2008-06-26 23:15:51 -03001890 .vidioc_querycap = vidioc_querycap,
1891 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1892 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1893 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1894 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1895 .vidioc_reqbufs = vidioc_reqbufs,
1896 .vidioc_querybuf = vidioc_querybuf,
1897 .vidioc_qbuf = vidioc_qbuf,
1898 .vidioc_dqbuf = vidioc_dqbuf,
1899 .vidioc_s_std = vidioc_s_std,
1900 .vidioc_enum_input = vidioc_enum_input,
1901 .vidioc_g_input = vidioc_g_input,
1902 .vidioc_s_input = vidioc_s_input,
1903 .vidioc_queryctrl = vidioc_queryctrl,
1904 .vidioc_g_ctrl = vidioc_g_ctrl,
1905 .vidioc_s_ctrl = vidioc_s_ctrl,
1906 .vidioc_streamon = vidioc_streamon,
1907 .vidioc_streamoff = vidioc_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001908 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1909 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001910 .vidioc_s_parm = vidioc_s_parm,
1911 .vidioc_g_parm = vidioc_g_parm,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001912 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuila3998102008-07-21 02:57:38 -03001913};
1914
Dean Andersonff7e22d2010-04-08 23:38:07 -03001915static void s2255_video_device_release(struct video_device *vdev)
1916{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001917 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
1918 dprintk(4, "%s, chnls: %d \n", __func__,
1919 atomic_read(&dev->num_channels));
1920 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001921 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001922 return;
1923}
1924
Hans Verkuila3998102008-07-21 02:57:38 -03001925static struct video_device template = {
1926 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001927 .fops = &s2255_fops_v4l,
1928 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001929 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001930 .tvnorms = S2255_NORMS,
1931 .current_norm = V4L2_STD_NTSC_M,
1932};
1933
1934static int s2255_probe_v4l(struct s2255_dev *dev)
1935{
1936 int ret;
1937 int i;
1938 int cur_nr = video_nr;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001939 struct s2255_channel *channel;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001940 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1941 if (ret)
1942 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001943 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001944 /* register 4 video devices */
1945 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001946 channel = &dev->channel[i];
1947 INIT_LIST_HEAD(&channel->vidq.active);
1948 channel->vidq.dev = dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001949 /* register 4 video devices */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001950 channel->vdev = template;
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001951 channel->vdev.lock = &dev->lock;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001952 channel->vdev.v4l2_dev = &dev->v4l2_dev;
1953 video_set_drvdata(&channel->vdev, channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03001954 if (video_nr == -1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001955 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001956 VFL_TYPE_GRABBER,
1957 video_nr);
1958 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001959 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001960 VFL_TYPE_GRABBER,
1961 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001962
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001963 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001964 dev_err(&dev->udev->dev,
1965 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001966 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001967 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001968 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001969 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001970 video_device_node_name(&channel->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001971
Dean Anderson38f993a2008-06-26 23:15:51 -03001972 }
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03001973 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %s\n",
1974 S2255_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001975 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001976 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001977 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001978 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001979 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001980 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001981 printk(KERN_WARNING "s2255: Not all channels available.\n");
1982 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001983}
1984
Dean Anderson38f993a2008-06-26 23:15:51 -03001985/* this function moves the usb stream read pipe data
1986 * into the system buffers.
1987 * returns 0 on success, EAGAIN if more data to process( call this
1988 * function again).
1989 *
1990 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001991 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001992 * bytes 4-7: channel: 0-3
1993 * bytes 8-11: payload size: size of the frame
1994 * bytes 12-payloadsize+12: frame data
1995 */
1996static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1997{
Dean Anderson38f993a2008-06-26 23:15:51 -03001998 char *pdest;
1999 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002000 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002001 char *psrc;
2002 unsigned long copy_size;
2003 unsigned long size;
2004 s32 idx = -1;
2005 struct s2255_framei *frm;
2006 unsigned char *pdata;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002007 struct s2255_channel *channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03002008 dprintk(100, "buffer to user\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002009 channel = &dev->channel[dev->cc];
2010 idx = channel->cur_frame;
2011 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002012 if (frm->ulState == S2255_READ_IDLE) {
2013 int jj;
2014 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03002015 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03002016 int payload;
2017 /* search for marker codes */
2018 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03002019 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002020 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03002021 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03002022 case S2255_MARKER_FRAME:
Dean Anderson14d96262008-08-25 13:58:55 -03002023 dprintk(4, "found frame marker at offset:"
2024 " %d [%x %x]\n", jj, pdata[0],
2025 pdata[1]);
2026 offset = jj + PREFIX_SIZE;
2027 bframe = 1;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002028 cc = le32_to_cpu(pdword[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03002029 if (cc >= MAX_CHANNELS) {
2030 printk(KERN_ERR
2031 "bad channel\n");
2032 return -EINVAL;
2033 }
2034 /* reverse it */
2035 dev->cc = G_chnmap[cc];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002036 channel = &dev->channel[dev->cc];
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002037 payload = le32_to_cpu(pdword[3]);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002038 if (payload > channel->req_image_size) {
2039 channel->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03002040 /* discard the bad frame */
2041 return -EINVAL;
2042 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002043 channel->pkt_size = payload;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002044 channel->jpg_size = le32_to_cpu(pdword[4]);
Dean Anderson14d96262008-08-25 13:58:55 -03002045 break;
2046 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002047
Dean Anderson14d96262008-08-25 13:58:55 -03002048 pdata += DEF_USB_BLOCK;
2049 jj += DEF_USB_BLOCK;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002050 if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002051 break;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002052 cc = G_chnmap[le32_to_cpu(pdword[1])];
Roel Kluinf14a2972009-10-23 07:59:42 -03002053 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002054 break;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002055 channel = &dev->channel[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002056 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03002057 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03002058 /* check if channel valid */
2059 /* set mode ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002060 channel->setmode_ready = 1;
2061 wake_up(&channel->wait_setmode);
Dean Anderson14d96262008-08-25 13:58:55 -03002062 dprintk(5, "setmode ready %d\n", cc);
2063 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002064 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002065 dev->chn_ready |= (1 << cc);
2066 if ((dev->chn_ready & 0x0f) != 0x0f)
2067 break;
2068 /* all channels ready */
2069 printk(KERN_INFO "s2255: fw loaded\n");
2070 atomic_set(&dev->fw_data->fw_state,
2071 S2255_FW_SUCCESS);
2072 wake_up(&dev->fw_data->wait_fw);
2073 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002074 case S2255_RESPONSE_STATUS:
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002075 channel->vidstatus = le32_to_cpu(pdword[3]);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002076 channel->vidstatus_ready = 1;
2077 wake_up(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002078 dprintk(5, "got vidstatus %x chan %d\n",
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002079 le32_to_cpu(pdword[3]), cc);
Dean Anderson4de39f52010-03-03 19:39:19 -03002080 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002081 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02002082 printk(KERN_INFO "s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002083 }
2084 default:
2085 pdata++;
2086 break;
2087 }
2088 if (bframe)
2089 break;
2090 } /* for */
2091 if (!bframe)
2092 return -EINVAL;
2093 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002094 channel = &dev->channel[dev->cc];
2095 idx = channel->cur_frame;
2096 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002097 /* search done. now find out if should be acquiring on this channel */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002098 if (!channel->b_acquire) {
Dean Anderson14d96262008-08-25 13:58:55 -03002099 /* we found a frame, but this channel is turned off */
2100 frm->ulState = S2255_READ_IDLE;
2101 return -EINVAL;
2102 }
2103
2104 if (frm->ulState == S2255_READ_IDLE) {
2105 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002106 frm->cur_size = 0;
2107 }
2108
Dean Anderson14d96262008-08-25 13:58:55 -03002109 /* skip the marker 512 bytes (and offset if out of sync) */
2110 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2111
Dean Anderson38f993a2008-06-26 23:15:51 -03002112
2113 if (frm->lpvbits == NULL) {
2114 dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
2115 frm, dev, dev->cc, idx);
2116 return -ENOMEM;
2117 }
2118
2119 pdest = frm->lpvbits + frm->cur_size;
2120
Dean Anderson14d96262008-08-25 13:58:55 -03002121 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002122
Dean Andersonfe85ce92010-06-01 19:12:07 -03002123 size = channel->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002124
Dean Anderson14d96262008-08-25 13:58:55 -03002125 /* sanity check on pdest */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002126 if ((copy_size + frm->cur_size) < channel->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03002127 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002128
Dean Anderson38f993a2008-06-26 23:15:51 -03002129 frm->cur_size += copy_size;
Dean Anderson14d96262008-08-25 13:58:55 -03002130 dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002131
Dean Anderson14d96262008-08-25 13:58:55 -03002132 if (frm->cur_size >= size) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002133 dprintk(2, "****************[%d]Buffer[%d]full*************\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002134 dev->cc, idx);
2135 channel->last_frame = channel->cur_frame;
2136 channel->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002137 /* end of system frame ring buffer, start at zero */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002138 if ((channel->cur_frame == SYS_FRAMES) ||
2139 (channel->cur_frame == channel->buffer.dwFrames))
2140 channel->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002141 /* frame ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002142 if (channel->b_acquire)
2143 s2255_got_frame(channel, channel->jpg_size);
2144 channel->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03002145 frm->ulState = S2255_READ_IDLE;
2146 frm->cur_size = 0;
2147
Dean Anderson38f993a2008-06-26 23:15:51 -03002148 }
2149 /* done successfully */
2150 return 0;
2151}
2152
2153static void s2255_read_video_callback(struct s2255_dev *dev,
2154 struct s2255_pipeinfo *pipe_info)
2155{
2156 int res;
2157 dprintk(50, "callback read video \n");
2158
2159 if (dev->cc >= MAX_CHANNELS) {
2160 dev->cc = 0;
2161 dev_err(&dev->udev->dev, "invalid channel\n");
2162 return;
2163 }
2164 /* otherwise copy to the system buffers */
2165 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002166 if (res != 0)
2167 dprintk(4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002168
2169 dprintk(50, "callback read video done\n");
2170 return;
2171}
2172
2173static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2174 u16 Index, u16 Value, void *TransferBuffer,
2175 s32 TransferBufferLength, int bOut)
2176{
2177 int r;
2178 if (!bOut) {
2179 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2180 Request,
2181 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2182 USB_DIR_IN,
2183 Value, Index, TransferBuffer,
2184 TransferBufferLength, HZ * 5);
2185 } else {
2186 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2187 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2188 Value, Index, TransferBuffer,
2189 TransferBufferLength, HZ * 5);
2190 }
2191 return r;
2192}
2193
2194/*
2195 * retrieve FX2 firmware version. future use.
2196 * @param dev pointer to device extension
2197 * @return -1 for fail, else returns firmware version as an int(16 bits)
2198 */
2199static int s2255_get_fx2fw(struct s2255_dev *dev)
2200{
2201 int fw;
2202 int ret;
2203 unsigned char transBuffer[64];
2204 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2205 S2255_VR_IN);
2206 if (ret < 0)
2207 dprintk(2, "get fw error: %x\n", ret);
2208 fw = transBuffer[0] + (transBuffer[1] << 8);
2209 dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
2210 return fw;
2211}
2212
2213/*
2214 * Create the system ring buffer to copy frames into from the
2215 * usb read pipe.
2216 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002217static int s2255_create_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002218{
2219 unsigned long i;
2220 unsigned long reqsize;
2221 dprintk(1, "create sys buffers\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002222 channel->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03002223 /* always allocate maximum size(PAL) for system buffers */
2224 reqsize = SYS_FRAMES_MAXSIZE;
2225
2226 if (reqsize > SYS_FRAMES_MAXSIZE)
2227 reqsize = SYS_FRAMES_MAXSIZE;
2228
2229 for (i = 0; i < SYS_FRAMES; i++) {
2230 /* allocate the frames */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002231 channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
2232 dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
2233 &channel->buffer.frame[i], channel->idx, i,
2234 channel->buffer.frame[i].lpvbits);
2235 channel->buffer.frame[i].size = reqsize;
2236 if (channel->buffer.frame[i].lpvbits == NULL) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002237 printk(KERN_INFO "out of memory. using less frames\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002238 channel->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002239 break;
2240 }
2241 }
2242
2243 /* make sure internal states are set */
2244 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002245 channel->buffer.frame[i].ulState = 0;
2246 channel->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002247 }
2248
Dean Andersonfe85ce92010-06-01 19:12:07 -03002249 channel->cur_frame = 0;
2250 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002251 return 0;
2252}
2253
Dean Andersonfe85ce92010-06-01 19:12:07 -03002254static int s2255_release_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002255{
2256 unsigned long i;
2257 dprintk(1, "release sys buffers\n");
2258 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002259 if (channel->buffer.frame[i].lpvbits) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002260 dprintk(1, "vfree %p\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002261 channel->buffer.frame[i].lpvbits);
2262 vfree(channel->buffer.frame[i].lpvbits);
Dean Anderson38f993a2008-06-26 23:15:51 -03002263 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002264 channel->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002265 }
2266 return 0;
2267}
2268
2269static int s2255_board_init(struct s2255_dev *dev)
2270{
Dean Anderson38f993a2008-06-26 23:15:51 -03002271 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2272 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002273 int j;
2274 struct s2255_pipeinfo *pipe = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002275 dprintk(4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002276 memset(pipe, 0, sizeof(*pipe));
2277 pipe->dev = dev;
2278 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2279 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002280
Dean Andersonab85c6a2010-04-08 23:39:12 -03002281 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2282 GFP_KERNEL);
2283 if (pipe->transfer_buffer == NULL) {
2284 dprintk(1, "out of memory!\n");
2285 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002286 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002287 /* query the firmware */
2288 fw_ver = s2255_get_fx2fw(dev);
2289
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -03002290 printk(KERN_INFO "s2255: usb firmware version %d.%d\n",
Dean Andersonabce21f2009-04-23 16:04:41 -03002291 (fw_ver >> 8) & 0xff,
2292 fw_ver & 0xff);
2293
2294 if (fw_ver < S2255_CUR_USB_FWVER)
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -03002295 printk(KERN_INFO "s2255: newer USB firmware available\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002296
2297 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002298 struct s2255_channel *channel = &dev->channel[j];
2299 channel->b_acquire = 0;
2300 channel->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002301 if (dev->pid == 0x2257 && j > 1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002302 channel->mode.color |= (1 << 16);
2303 channel->jc.quality = S2255_DEF_JPEG_QUAL;
2304 channel->width = LINE_SZ_4CIFS_NTSC;
2305 channel->height = NUM_LINES_4CIFS_NTSC * 2;
2306 channel->fmt = &formats[0];
2307 channel->mode.restart = 1;
2308 channel->req_image_size = get_transfer_size(&mode_def);
2309 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002310 /* create the system buffers */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002311 s2255_create_sys_buffers(channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03002312 }
2313 /* start read pipe */
2314 s2255_start_readpipe(dev);
Dean Anderson85b85482010-04-08 23:51:17 -03002315 dprintk(1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002316 return 0;
2317}
2318
2319static int s2255_board_shutdown(struct s2255_dev *dev)
2320{
2321 u32 i;
Dean Anderson85b85482010-04-08 23:51:17 -03002322 dprintk(1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002323
2324 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002325 if (dev->channel[i].b_acquire)
2326 s2255_stop_acquire(&dev->channel[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002327 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002328 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002329 for (i = 0; i < MAX_CHANNELS; i++)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002330 s2255_release_sys_buffers(&dev->channel[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002331 /* release transfer buffer */
2332 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002333 return 0;
2334}
2335
2336static void read_pipe_completion(struct urb *purb)
2337{
2338 struct s2255_pipeinfo *pipe_info;
2339 struct s2255_dev *dev;
2340 int status;
2341 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002342 pipe_info = purb->context;
Dean Anderson85b85482010-04-08 23:51:17 -03002343 dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
Dean Anderson38f993a2008-06-26 23:15:51 -03002344 purb->status);
2345 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002346 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002347 return;
2348 }
2349
2350 dev = pipe_info->dev;
2351 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002352 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002353 return;
2354 }
2355 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002356 /* if shutting down, do not resubmit, exit immediately */
2357 if (status == -ESHUTDOWN) {
Dean Anderson85b85482010-04-08 23:51:17 -03002358 dprintk(2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002359 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002360 return;
2361 }
2362
2363 if (pipe_info->state == 0) {
Dean Anderson85b85482010-04-08 23:51:17 -03002364 dprintk(2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002365 return;
2366 }
2367
Dean Andersonb02064c2009-04-30 12:29:38 -03002368 if (status == 0)
2369 s2255_read_video_callback(dev, pipe_info);
2370 else {
2371 pipe_info->err_count++;
Dean Anderson85b85482010-04-08 23:51:17 -03002372 dprintk(1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002373 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002374
Dean Anderson38f993a2008-06-26 23:15:51 -03002375 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2376 /* reuse urb */
2377 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2378 pipe,
2379 pipe_info->transfer_buffer,
2380 pipe_info->cur_transfer_size,
2381 read_pipe_completion, pipe_info);
2382
2383 if (pipe_info->state != 0) {
Pete Eberleina1b4c862011-04-01 21:21:26 -03002384 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002385 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002386 }
2387 } else {
Dean Anderson85b85482010-04-08 23:51:17 -03002388 dprintk(2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002389 }
2390 return;
2391}
2392
2393static int s2255_start_readpipe(struct s2255_dev *dev)
2394{
2395 int pipe;
2396 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002397 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002398 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
Dean Anderson85b85482010-04-08 23:51:17 -03002399 dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002400 pipe_info->state = 1;
2401 pipe_info->err_count = 0;
2402 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2403 if (!pipe_info->stream_urb) {
2404 dev_err(&dev->udev->dev,
2405 "ReadStream: Unable to alloc URB\n");
2406 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002407 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002408 /* transfer buffer allocated in board_init */
2409 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2410 pipe,
2411 pipe_info->transfer_buffer,
2412 pipe_info->cur_transfer_size,
2413 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002414 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2415 if (retval) {
2416 printk(KERN_ERR "s2255: start read pipe failed\n");
2417 return retval;
2418 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002419 return 0;
2420}
2421
2422/* starts acquisition process */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002423static int s2255_start_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002424{
2425 unsigned char *buffer;
2426 int res;
2427 unsigned long chn_rev;
2428 int j;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002429 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2430 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002431 buffer = kzalloc(512, GFP_KERNEL);
2432 if (buffer == NULL) {
2433 dev_err(&dev->udev->dev, "out of mem\n");
2434 return -ENOMEM;
2435 }
2436
Dean Andersonfe85ce92010-06-01 19:12:07 -03002437 channel->last_frame = -1;
2438 channel->bad_payload = 0;
2439 channel->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002440 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002441 channel->buffer.frame[j].ulState = 0;
2442 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002443 }
2444
2445 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002446 *(__le32 *) buffer = IN_DATA_TOKEN;
2447 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2448 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002449 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2450 if (res != 0)
2451 dev_err(&dev->udev->dev, "CMD_START error\n");
2452
Dean Andersonfe85ce92010-06-01 19:12:07 -03002453 dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03002454 kfree(buffer);
2455 return 0;
2456}
2457
Dean Andersonfe85ce92010-06-01 19:12:07 -03002458static int s2255_stop_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002459{
2460 unsigned char *buffer;
2461 int res;
2462 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002463 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2464 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002465 buffer = kzalloc(512, GFP_KERNEL);
2466 if (buffer == NULL) {
2467 dev_err(&dev->udev->dev, "out of mem\n");
2468 return -ENOMEM;
2469 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002470 /* send the stop command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002471 *(__le32 *) buffer = IN_DATA_TOKEN;
2472 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2473 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002474 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002475 if (res != 0)
2476 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002477 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002478 channel->b_acquire = 0;
2479 dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
Dean Anderson14d96262008-08-25 13:58:55 -03002480 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002481}
2482
2483static void s2255_stop_readpipe(struct s2255_dev *dev)
2484{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002485 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002486
Dean Andersonab85c6a2010-04-08 23:39:12 -03002487 pipe->state = 0;
2488 if (pipe->stream_urb) {
2489 /* cancel urb */
2490 usb_kill_urb(pipe->stream_urb);
2491 usb_free_urb(pipe->stream_urb);
2492 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002493 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002494 dprintk(4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002495 return;
2496}
2497
Dean Anderson14d96262008-08-25 13:58:55 -03002498static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002499{
Dean Anderson14d96262008-08-25 13:58:55 -03002500 if (reset)
2501 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002502 dev->fw_data->fw_size = dev->fw_data->fw->size;
2503 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2504 memcpy(dev->fw_data->pfw_data,
2505 dev->fw_data->fw->data, CHUNK_SIZE);
2506 dev->fw_data->fw_loaded = CHUNK_SIZE;
2507 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2508 usb_sndbulkpipe(dev->udev, 2),
2509 dev->fw_data->pfw_data,
2510 CHUNK_SIZE, s2255_fwchunk_complete,
2511 dev->fw_data);
2512 mod_timer(&dev->timer, jiffies + HZ);
2513}
2514
2515/* standard usb probe function */
2516static int s2255_probe(struct usb_interface *interface,
2517 const struct usb_device_id *id)
2518{
2519 struct s2255_dev *dev = NULL;
2520 struct usb_host_interface *iface_desc;
2521 struct usb_endpoint_descriptor *endpoint;
2522 int i;
2523 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002524 __le32 *pdata;
2525 int fw_size;
Dean Anderson85b85482010-04-08 23:51:17 -03002526 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002527 /* allocate memory for our device state and initialize it to zero */
2528 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2529 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002530 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002531 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002532 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002533 atomic_set(&dev->num_channels, 0);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002534 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002535 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2536 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002537 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002538 mutex_init(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002539 /* grab usb_device and save it */
2540 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2541 if (dev->udev == NULL) {
2542 dev_err(&interface->dev, "null usb device\n");
2543 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002544 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002545 }
Dean Andersond62e85a2010-04-09 19:54:26 -03002546 dprintk(1, "dev: %p, udev %p interface %p\n", dev,
Dean Anderson38f993a2008-06-26 23:15:51 -03002547 dev->udev, interface);
2548 dev->interface = interface;
2549 /* set up the endpoint information */
2550 iface_desc = interface->cur_altsetting;
2551 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2552 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2553 endpoint = &iface_desc->endpoint[i].desc;
2554 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2555 /* we found the bulk in endpoint */
2556 dev->read_endpoint = endpoint->bEndpointAddress;
2557 }
2558 }
2559
2560 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002561 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002562 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002563 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002564 init_timer(&dev->timer);
2565 dev->timer.function = s2255_timer;
2566 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002567 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002568 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002569 struct s2255_channel *channel = &dev->channel[i];
2570 dev->channel[i].idx = i;
2571 init_waitqueue_head(&channel->wait_setmode);
2572 init_waitqueue_head(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002573 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002574
2575 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002576 if (!dev->fw_data->fw_urb) {
2577 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002578 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002579 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002580
Dean Anderson38f993a2008-06-26 23:15:51 -03002581 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2582 if (!dev->fw_data->pfw_data) {
2583 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002584 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002585 }
2586 /* load the first chunk */
2587 if (request_firmware(&dev->fw_data->fw,
2588 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2589 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002590 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002591 }
Dean Anderson14d96262008-08-25 13:58:55 -03002592 /* check the firmware is valid */
2593 fw_size = dev->fw_data->fw->size;
2594 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002595
Dean Anderson14d96262008-08-25 13:58:55 -03002596 if (*pdata != S2255_FW_MARKER) {
2597 printk(KERN_INFO "Firmware invalid.\n");
2598 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002599 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002600 } else {
2601 /* make sure firmware is the latest */
2602 __le32 *pRel;
2603 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2604 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002605 dev->dsp_fw_ver = le32_to_cpu(*pRel);
2606 if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
Dean Anderson4de39f52010-03-03 19:39:19 -03002607 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002608 if (dev->pid == 0x2257 &&
2609 dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002610 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
Dean Andersonfe85ce92010-06-01 19:12:07 -03002611 " or above.\n", S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002612 }
Dean Anderson14d96262008-08-25 13:58:55 -03002613 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002614 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002615 retval = s2255_board_init(dev);
2616 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002617 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002618 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002619 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002620 /* loads v4l specific */
2621 retval = s2255_probe_v4l(dev);
2622 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002623 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002624 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2625 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002626errorBOARDINIT:
2627 s2255_board_shutdown(dev);
2628errorFWMARKER:
2629 release_firmware(dev->fw_data->fw);
2630errorREQFW:
2631 kfree(dev->fw_data->pfw_data);
2632errorFWDATA2:
2633 usb_free_urb(dev->fw_data->fw_urb);
2634errorFWURB:
2635 del_timer(&dev->timer);
2636errorEP:
2637 usb_put_dev(dev->udev);
2638errorUDEV:
2639 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002640 mutex_destroy(&dev->lock);
2641errorFWDATA1:
2642 kfree(dev);
2643 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002644 return retval;
2645}
2646
2647/* disconnect routine. when board is removed physically or with rmmod */
2648static void s2255_disconnect(struct usb_interface *interface)
2649{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002650 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002651 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002652 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002653 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002654 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002655 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002656 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002657 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002658 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002659 for (i = 0; i < channels; i++)
2660 video_unregister_device(&dev->channel[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002661 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002662 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2663 wake_up(&dev->fw_data->wait_fw);
2664 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002665 dev->channel[i].setmode_ready = 1;
2666 wake_up(&dev->channel[i].wait_setmode);
2667 dev->channel[i].vidstatus_ready = 1;
2668 wake_up(&dev->channel[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002669 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002670 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002671 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002672 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002673}
2674
2675static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002676 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002677 .probe = s2255_probe,
2678 .disconnect = s2255_disconnect,
2679 .id_table = s2255_table,
2680};
2681
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002682module_usb_driver(s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002683
2684MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2685MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2686MODULE_LICENSE("GPL");
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03002687MODULE_VERSION(S2255_VERSION);
Tim Gardner1bec9822012-07-24 16:52:27 -03002688MODULE_FIRMWARE(FIRMWARE_FILE_NAME);