blob: 46506d8381a2562c4593f524cef204b325aed2b7 [file] [log] [blame]
Dean Anderson38f993a2008-06-26 23:15:51 -03001/*
2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
3 *
Dean Anderson4de39f52010-03-03 19:39:19 -03004 * Copyright (C) 2007-2010 by Sensoray Company Inc.
Dean Anderson38f993a2008-06-26 23:15:51 -03005 * Dean Anderson
6 *
7 * Some video buffer code based on vivi driver:
8 *
9 * Sensoray 2255 device supports 4 simultaneous channels.
10 * The channels are not "crossbar" inputs, they are physically
11 * attached to separate video decoders.
12 *
13 * Because of USB2.0 bandwidth limitations. There is only a
14 * certain amount of data which may be transferred at one time.
15 *
16 * Example maximum bandwidth utilization:
17 *
18 * -full size, color mode YUYV or YUV422P: 2 channels at once
19 *
20 * -full or half size Grey scale: all 4 channels at once
21 *
22 * -half size, color mode YUYV or YUV422P: all 4 channels at once
23 *
24 * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
25 * at once.
26 * (TODO: Incorporate videodev2 frame rate(FR) enumeration,
27 * which is currently experimental.)
28 *
29 * This program is free software; you can redistribute it and/or modify
30 * it under the terms of the GNU General Public License as published by
31 * the Free Software Foundation; either version 2 of the License, or
32 * (at your option) any later version.
33 *
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
38 *
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42 */
43
44#include <linux/module.h>
45#include <linux/firmware.h>
46#include <linux/kernel.h>
47#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090048#include <linux/slab.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030049#include <linux/videodev2.h>
50#include <linux/version.h>
Hans Verkuilfeb75f02008-07-27 06:30:21 -030051#include <linux/mm.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030052#include <media/videobuf-vmalloc.h>
53#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030054#include <media/v4l2-device.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030055#include <media/v4l2-ioctl.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030056#include <linux/vmalloc.h>
57#include <linux/usb.h>
58
Dean Anderson85b85482010-04-08 23:51:17 -030059#define S2255_MAJOR_VERSION 1
sensoray-dev752eb7a2011-01-19 17:41:45 -030060#define S2255_MINOR_VERSION 21
Dean Anderson85b85482010-04-08 23:51:17 -030061#define S2255_RELEASE 0
62#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
63 S2255_MINOR_VERSION, \
64 S2255_RELEASE)
Dean Anderson38f993a2008-06-26 23:15:51 -030065#define FIRMWARE_FILE_NAME "f2255usb.bin"
66
Dean Anderson22b88d42008-08-29 15:33:19 -030067/* default JPEG quality */
68#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030069/* vendor request in */
70#define S2255_VR_IN 0
71/* vendor request out */
72#define S2255_VR_OUT 1
73/* firmware query */
74#define S2255_VR_FW 0x30
75/* USB endpoint number for configuring the device */
76#define S2255_CONFIG_EP 2
77/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030078#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030079/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030080#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson38f993a2008-06-26 23:15:51 -030081#define S2255_DEF_BUFS 16
Dean Anderson14d96262008-08-25 13:58:55 -030082#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030083#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030084#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
85#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
86#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
87#define S2255_RESPONSE_FW cpu_to_le32(0x10)
88#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030089#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030090#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030091#define SYS_FRAMES 4
92/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030093#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
94#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030095#define LINE_SZ_4CIFS_NTSC 640
96#define LINE_SZ_2CIFS_NTSC 640
97#define LINE_SZ_1CIFS_NTSC 320
98#define LINE_SZ_4CIFS_PAL 704
99#define LINE_SZ_2CIFS_PAL 704
100#define LINE_SZ_1CIFS_PAL 352
101#define NUM_LINES_4CIFS_NTSC 240
102#define NUM_LINES_2CIFS_NTSC 240
103#define NUM_LINES_1CIFS_NTSC 240
104#define NUM_LINES_4CIFS_PAL 288
105#define NUM_LINES_2CIFS_PAL 288
106#define NUM_LINES_1CIFS_PAL 288
107#define LINE_SZ_DEF 640
108#define NUM_LINES_DEF 240
109
110
111/* predefined settings */
112#define FORMAT_NTSC 1
113#define FORMAT_PAL 2
114
115#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
116#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
117#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300118/* SCALE_4CIFSI is the 2 fields interpolated into one */
119#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300120
121#define COLOR_YUVPL 1 /* YUV planar */
122#define COLOR_YUVPK 2 /* YUV packed */
123#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300124#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300125
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300126#define MASK_COLOR 0x000000ff
127#define MASK_JPG_QUALITY 0x0000ff00
128#define MASK_INPUT_TYPE 0x000f0000
Dean Anderson38f993a2008-06-26 23:15:51 -0300129/* frame decimation. Not implemented by V4L yet(experimental in V4L) */
130#define FDEC_1 1 /* capture every frame. default */
131#define FDEC_2 2 /* capture every 2nd frame */
132#define FDEC_3 3 /* capture every 3rd frame */
133#define FDEC_5 5 /* capture every 5th frame */
134
135/*-------------------------------------------------------
136 * Default mode parameters.
137 *-------------------------------------------------------*/
138#define DEF_SCALE SCALE_4CIFS
139#define DEF_COLOR COLOR_YUVPL
140#define DEF_FDEC FDEC_1
141#define DEF_BRIGHT 0
142#define DEF_CONTRAST 0x5c
143#define DEF_SATURATION 0x80
144#define DEF_HUE 0
145
146/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300147#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
148#define CMD_2255 cpu_to_le32(0xc2255000)
149#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
150#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
151#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
152#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300153
154struct s2255_mode {
155 u32 format; /* input video format (NTSC, PAL) */
156 u32 scale; /* output video scale */
157 u32 color; /* output video color format */
158 u32 fdec; /* frame decimation */
159 u32 bright; /* brightness */
160 u32 contrast; /* contrast */
161 u32 saturation; /* saturation */
162 u32 hue; /* hue (NTSC only)*/
163 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
164 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
165 u32 restart; /* if DSP requires restart */
166};
167
Dean Anderson14d96262008-08-25 13:58:55 -0300168
169#define S2255_READ_IDLE 0
170#define S2255_READ_FRAME 1
171
Dean Anderson38f993a2008-06-26 23:15:51 -0300172/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300173struct s2255_framei {
174 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300175 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300176 void *lpvbits; /* image data */
177 unsigned long cur_size; /* current data copied to it */
178};
179
180/* image buffer structure */
181struct s2255_bufferi {
182 unsigned long dwFrames; /* number of frames in buffer */
183 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
184};
185
186#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
187 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300188 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300189
190struct s2255_dmaqueue {
191 struct list_head active;
Dean Anderson38f993a2008-06-26 23:15:51 -0300192 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300193};
194
195/* for firmware loading, fw_state */
196#define S2255_FW_NOTLOADED 0
197#define S2255_FW_LOADED_DSPWAIT 1
198#define S2255_FW_SUCCESS 2
199#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300200#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300201#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300202/* 2255 read states */
203#define S2255_READ_IDLE 0
204#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300205struct s2255_fw {
206 int fw_loaded;
207 int fw_size;
208 struct urb *fw_urb;
209 atomic_t fw_state;
210 void *pfw_data;
211 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300212 const struct firmware *fw;
213};
214
215struct s2255_pipeinfo {
216 u32 max_transfer_size;
217 u32 cur_transfer_size;
218 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300219 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300220 void *stream_urb;
221 void *dev; /* back pointer to s2255_dev struct*/
222 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300223 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300224};
225
226struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300227struct s2255_dev;
228
229struct s2255_channel {
230 struct video_device vdev;
231 int resources;
232 struct s2255_dmaqueue vidq;
233 struct s2255_bufferi buffer;
234 struct s2255_mode mode;
235 /* jpeg compression */
236 struct v4l2_jpegcompression jc;
237 /* capture parameters (for high quality mode full size) */
238 struct v4l2_captureparm cap_parm;
239 int cur_frame;
240 int last_frame;
241
242 int b_acquire;
243 /* allocated image size */
244 unsigned long req_image_size;
245 /* received packet size */
246 unsigned long pkt_size;
247 int bad_payload;
248 unsigned long frame_count;
249 /* if JPEG image */
250 int jpg_size;
251 /* if channel configured to default state */
252 int configured;
253 wait_queue_head_t wait_setmode;
254 int setmode_ready;
255 /* video status items */
256 int vidstatus;
257 wait_queue_head_t wait_vidstatus;
258 int vidstatus_ready;
259 unsigned int width;
260 unsigned int height;
261 const struct s2255_fmt *fmt;
262 int idx; /* channel number on device, 0-3 */
263};
264
Dean Anderson38f993a2008-06-26 23:15:51 -0300265
266struct s2255_dev {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300267 struct s2255_channel channel[MAX_CHANNELS];
Dean Anderson65c6edb2010-04-20 17:21:32 -0300268 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300269 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300270 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300271 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson38f993a2008-06-26 23:15:51 -0300272 struct mutex open_lock;
Dean Anderson38f993a2008-06-26 23:15:51 -0300273 struct usb_device *udev;
274 struct usb_interface *interface;
275 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300276 struct timer_list timer;
277 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300278 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300279 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300280 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300281 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300282 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300283 /* dsp firmware version (f2255usb.bin) */
284 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300285 u16 pid; /* product id */
Dean Anderson38f993a2008-06-26 23:15:51 -0300286};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300287
Dean Anderson65c6edb2010-04-20 17:21:32 -0300288static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
289{
290 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
291}
Dean Anderson38f993a2008-06-26 23:15:51 -0300292
293struct s2255_fmt {
294 char *name;
295 u32 fourcc;
296 int depth;
297};
298
299/* buffer for one video frame */
300struct s2255_buffer {
301 /* common v4l buffer stuff -- must be first */
302 struct videobuf_buffer vb;
303 const struct s2255_fmt *fmt;
304};
305
306struct s2255_fh {
307 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300308 struct videobuf_queue vb_vidq;
309 enum v4l2_buf_type type;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300310 struct s2255_channel *channel;
311 int resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300312};
313
Dean Andersonabce21f2009-04-23 16:04:41 -0300314/* current cypress EEPROM firmware version */
sensoray-dev752eb7a2011-01-19 17:41:45 -0300315#define S2255_CUR_USB_FWVER ((3 << 8) | 11)
Dean Anderson4de39f52010-03-03 19:39:19 -0300316/* current DSP FW version */
sensoray-dev752eb7a2011-01-19 17:41:45 -0300317#define S2255_CUR_DSP_FWVER 10102
Dean Anderson4de39f52010-03-03 19:39:19 -0300318/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300319#define S2255_MIN_DSP_STATUS 5
320#define S2255_MIN_DSP_COLORFILTER 8
Dean Anderson38f993a2008-06-26 23:15:51 -0300321#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300322
323/* private V4L2 controls */
324
325/*
326 * The following chart displays how COLORFILTER should be set
327 * =========================================================
328 * = fourcc = COLORFILTER =
329 * = ===============================
330 * = = 0 = 1 =
331 * =========================================================
332 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
333 * = = s-video or = composite =
334 * = = B/W camera = input =
335 * =========================================================
336 * = other = color, svideo = color, =
337 * = = = composite =
338 * =========================================================
339 *
340 * Notes:
341 * channels 0-3 on 2255 are composite
342 * channels 0-1 on 2257 are composite, 2-3 are s-video
343 * If COLORFILTER is 0 with a composite color camera connected,
344 * the output will appear monochrome but hatching
345 * will occur.
346 * COLORFILTER is different from "color killer" and "color effects"
347 * for reasons above.
348 */
349#define S2255_V4L2_YC_ON 1
350#define S2255_V4L2_YC_OFF 0
351#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
352
Dean Anderson38f993a2008-06-26 23:15:51 -0300353/* frame prefix size (sent once every frame) */
354#define PREFIX_SIZE 512
355
356/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300357static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300358
Dean Anderson38f993a2008-06-26 23:15:51 -0300359static int debug;
360static int *s2255_debug = &debug;
361
362static int s2255_start_readpipe(struct s2255_dev *dev);
363static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300364static int s2255_start_acquire(struct s2255_channel *channel);
365static int s2255_stop_acquire(struct s2255_channel *channel);
366static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
367 int jpgsize);
368static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300369static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300370static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300371static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300372static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
373 u16 index, u16 value, void *buf,
374 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300375
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300376/* dev_err macro with driver name */
377#define S2255_DRIVER_NAME "s2255"
378#define s2255_dev_err(dev, fmt, arg...) \
379 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
380
Dean Anderson38f993a2008-06-26 23:15:51 -0300381#define dprintk(level, fmt, arg...) \
382 do { \
383 if (*s2255_debug >= (level)) { \
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300384 printk(KERN_DEBUG S2255_DRIVER_NAME \
385 ": " fmt, ##arg); \
Dean Anderson38f993a2008-06-26 23:15:51 -0300386 } \
387 } while (0)
388
Dean Anderson38f993a2008-06-26 23:15:51 -0300389static struct usb_driver s2255_driver;
390
Dean Anderson38f993a2008-06-26 23:15:51 -0300391/* Declare static vars that will be used as parameters */
392static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
393
394/* start video number */
395static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
396
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300397module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300398MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300399module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300400MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300401module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300402MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
403
404/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300405#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300406static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300407 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
408 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300409 { } /* Terminating entry */
410};
411MODULE_DEVICE_TABLE(usb, s2255_table);
412
Dean Anderson38f993a2008-06-26 23:15:51 -0300413#define BUFFER_TIMEOUT msecs_to_jiffies(400)
414
Dean Anderson38f993a2008-06-26 23:15:51 -0300415/* image formats. */
416static const struct s2255_fmt formats[] = {
417 {
418 .name = "4:2:2, planar, YUV422P",
419 .fourcc = V4L2_PIX_FMT_YUV422P,
420 .depth = 16
421
422 }, {
423 .name = "4:2:2, packed, YUYV",
424 .fourcc = V4L2_PIX_FMT_YUYV,
425 .depth = 16
426
427 }, {
428 .name = "4:2:2, packed, UYVY",
429 .fourcc = V4L2_PIX_FMT_UYVY,
430 .depth = 16
431 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300432 .name = "JPG",
433 .fourcc = V4L2_PIX_FMT_JPEG,
434 .depth = 24
435 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300436 .name = "MJPG",
437 .fourcc = V4L2_PIX_FMT_MJPEG,
438 .depth = 24
439 }, {
Dean Anderson38f993a2008-06-26 23:15:51 -0300440 .name = "8bpp GREY",
441 .fourcc = V4L2_PIX_FMT_GREY,
442 .depth = 8
443 }
444};
445
446static int norm_maxw(struct video_device *vdev)
447{
448 return (vdev->current_norm & V4L2_STD_NTSC) ?
449 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
450}
451
452static int norm_maxh(struct video_device *vdev)
453{
454 return (vdev->current_norm & V4L2_STD_NTSC) ?
455 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
456}
457
458static int norm_minw(struct video_device *vdev)
459{
460 return (vdev->current_norm & V4L2_STD_NTSC) ?
461 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
462}
463
464static int norm_minh(struct video_device *vdev)
465{
466 return (vdev->current_norm & V4L2_STD_NTSC) ?
467 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
468}
469
470
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300471/*
472 * TODO: fixme: move YUV reordering to hardware
473 * converts 2255 planar format to yuyv or uyvy
474 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300475static void planar422p_to_yuv_packed(const unsigned char *in,
476 unsigned char *out,
477 int width, int height,
478 int fmt)
479{
480 unsigned char *pY;
481 unsigned char *pCb;
482 unsigned char *pCr;
483 unsigned long size = height * width;
484 unsigned int i;
485 pY = (unsigned char *)in;
486 pCr = (unsigned char *)in + height * width;
487 pCb = (unsigned char *)in + height * width + (height * width / 2);
488 for (i = 0; i < size * 2; i += 4) {
489 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
490 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
491 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
492 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
493 }
494 return;
495}
496
Hans Verkuild45b9b82008-09-04 03:33:43 -0300497static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300498{
sensoray-dev752eb7a2011-01-19 17:41:45 -0300499 s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b01, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300500 msleep(10);
501 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300502 msleep(600);
503 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300504 return;
505}
Dean Anderson38f993a2008-06-26 23:15:51 -0300506
507/* kickstarts the firmware loading. from probe
508 */
509static void s2255_timer(unsigned long user_data)
510{
511 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson85b85482010-04-08 23:51:17 -0300512 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300513 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
514 printk(KERN_ERR "s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300515 atomic_set(&data->fw_state, S2255_FW_FAILED);
516 /* wake up anything waiting for the firmware */
517 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300518 return;
519 }
520}
521
Dean Anderson38f993a2008-06-26 23:15:51 -0300522
523/* this loads the firmware asynchronously.
524 Originally this was done synchroously in probe.
525 But it is better to load it asynchronously here than block
526 inside the probe function. Blocking inside probe affects boot time.
527 FW loading is triggered by the timer in the probe function
528*/
529static void s2255_fwchunk_complete(struct urb *urb)
530{
531 struct s2255_fw *data = urb->context;
532 struct usb_device *udev = urb->dev;
533 int len;
Dean Anderson85b85482010-04-08 23:51:17 -0300534 dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
Dean Anderson38f993a2008-06-26 23:15:51 -0300535 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300536 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300537 atomic_set(&data->fw_state, S2255_FW_FAILED);
538 /* wake up anything waiting for the firmware */
539 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300540 return;
541 }
542 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300543 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300544 atomic_set(&data->fw_state, S2255_FW_FAILED);
545 /* wake up anything waiting for the firmware */
546 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300547 return;
548 }
549#define CHUNK_SIZE 512
550 /* all USB transfers must be done with continuous kernel memory.
551 can't allocate more than 128k in current linux kernel, so
552 upload the firmware in chunks
553 */
554 if (data->fw_loaded < data->fw_size) {
555 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
556 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
557
558 if (len < CHUNK_SIZE)
559 memset(data->pfw_data, 0, CHUNK_SIZE);
560
561 dprintk(100, "completed len %d, loaded %d \n", len,
562 data->fw_loaded);
563
564 memcpy(data->pfw_data,
565 (char *) data->fw->data + data->fw_loaded, len);
566
567 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
568 data->pfw_data, CHUNK_SIZE,
569 s2255_fwchunk_complete, data);
570 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
571 dev_err(&udev->dev, "failed submit URB\n");
572 atomic_set(&data->fw_state, S2255_FW_FAILED);
573 /* wake up anything waiting for the firmware */
574 wake_up(&data->wait_fw);
575 return;
576 }
577 data->fw_loaded += len;
578 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300579 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson85b85482010-04-08 23:51:17 -0300580 dprintk(100, "%s: firmware upload complete\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300581 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300582 return;
583
584}
585
Dean Andersonfe85ce92010-06-01 19:12:07 -0300586static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300587{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300588 struct s2255_dmaqueue *dma_q = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300589 struct s2255_buffer *buf;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300590 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300591 unsigned long flags = 0;
592 int rc = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300593 spin_lock_irqsave(&dev->slock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300594 if (list_empty(&dma_q->active)) {
595 dprintk(1, "No active queue to serve\n");
596 rc = -1;
597 goto unlock;
598 }
599 buf = list_entry(dma_q->active.next,
600 struct s2255_buffer, vb.queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300601 list_del(&buf->vb.queue);
602 do_gettimeofday(&buf->vb.ts);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300603 s2255_fillbuff(channel, buf, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300604 wake_up(&buf->vb.done);
Dean Anderson85b85482010-04-08 23:51:17 -0300605 dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
Dean Anderson38f993a2008-06-26 23:15:51 -0300606unlock:
607 spin_unlock_irqrestore(&dev->slock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300608 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300609}
610
Dean Anderson38f993a2008-06-26 23:15:51 -0300611static const struct s2255_fmt *format_by_fourcc(int fourcc)
612{
613 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300614 for (i = 0; i < ARRAY_SIZE(formats); i++) {
615 if (-1 == formats[i].fourcc)
616 continue;
617 if (formats[i].fourcc == fourcc)
618 return formats + i;
619 }
620 return NULL;
621}
622
Dean Anderson38f993a2008-06-26 23:15:51 -0300623/* video buffer vmalloc implementation based partly on VIVI driver which is
624 * Copyright (c) 2006 by
625 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
626 * Ted Walther <ted--a.t--enumera.com>
627 * John Sokol <sokol--a.t--videotechnology.com>
628 * http://v4l.videotechnology.com/
629 *
630 */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300631static void s2255_fillbuff(struct s2255_channel *channel,
632 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300633{
634 int pos = 0;
635 struct timeval ts;
636 const char *tmpbuf;
637 char *vbuf = videobuf_to_vmalloc(&buf->vb);
638 unsigned long last_frame;
639 struct s2255_framei *frm;
640
641 if (!vbuf)
642 return;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300643 last_frame = channel->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300644 if (last_frame != -1) {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300645 frm = &channel->buffer.frame[last_frame];
Dean Anderson38f993a2008-06-26 23:15:51 -0300646 tmpbuf =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300647 (const char *)channel->buffer.frame[last_frame].lpvbits;
Dean Anderson38f993a2008-06-26 23:15:51 -0300648 switch (buf->fmt->fourcc) {
649 case V4L2_PIX_FMT_YUYV:
650 case V4L2_PIX_FMT_UYVY:
651 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
652 vbuf, buf->vb.width,
653 buf->vb.height,
654 buf->fmt->fourcc);
655 break;
656 case V4L2_PIX_FMT_GREY:
657 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
658 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300659 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300660 case V4L2_PIX_FMT_MJPEG:
Dean Anderson14d96262008-08-25 13:58:55 -0300661 buf->vb.size = jpgsize;
662 memcpy(vbuf, tmpbuf, buf->vb.size);
663 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300664 case V4L2_PIX_FMT_YUV422P:
665 memcpy(vbuf, tmpbuf,
666 buf->vb.width * buf->vb.height * 2);
667 break;
668 default:
669 printk(KERN_DEBUG "s2255: unknown format?\n");
670 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300671 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300672 } else {
673 printk(KERN_ERR "s2255: =======no frame\n");
674 return;
675
676 }
677 dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
678 (unsigned long)vbuf, pos);
679 /* tell v4l buffer was filled */
680
Dean Andersonfe85ce92010-06-01 19:12:07 -0300681 buf->vb.field_count = channel->frame_count * 2;
Dean Anderson38f993a2008-06-26 23:15:51 -0300682 do_gettimeofday(&ts);
683 buf->vb.ts = ts;
684 buf->vb.state = VIDEOBUF_DONE;
685}
686
687
688/* ------------------------------------------------------------------
689 Videobuf operations
690 ------------------------------------------------------------------*/
691
692static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
693 unsigned int *size)
694{
695 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300696 struct s2255_channel *channel = fh->channel;
697 *size = channel->width * channel->height * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300698
699 if (0 == *count)
700 *count = S2255_DEF_BUFS;
701
Andreas Bombedab7e312010-03-21 16:02:45 -0300702 if (*size * *count > vid_limit * 1024 * 1024)
703 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300704
705 return 0;
706}
707
708static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
709{
710 dprintk(4, "%s\n", __func__);
711
Dean Anderson38f993a2008-06-26 23:15:51 -0300712 videobuf_vmalloc_free(&buf->vb);
713 buf->vb.state = VIDEOBUF_NEEDS_INIT;
714}
715
716static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
717 enum v4l2_field field)
718{
719 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300720 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300721 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
722 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300723 int w = channel->width;
724 int h = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300725 dprintk(4, "%s, field=%d\n", __func__, field);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300726 if (channel->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300727 return -EINVAL;
728
Dean Andersonfe85ce92010-06-01 19:12:07 -0300729 if ((w < norm_minw(&channel->vdev)) ||
730 (w > norm_maxw(&channel->vdev)) ||
731 (h < norm_minh(&channel->vdev)) ||
732 (h > norm_maxh(&channel->vdev))) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300733 dprintk(4, "invalid buffer prepare\n");
734 return -EINVAL;
735 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300736 buf->vb.size = w * h * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300737 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
738 dprintk(4, "invalid buffer prepare\n");
739 return -EINVAL;
740 }
741
Dean Andersonfe85ce92010-06-01 19:12:07 -0300742 buf->fmt = channel->fmt;
743 buf->vb.width = w;
744 buf->vb.height = h;
Dean Anderson38f993a2008-06-26 23:15:51 -0300745 buf->vb.field = field;
746
Dean Anderson38f993a2008-06-26 23:15:51 -0300747 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
748 rc = videobuf_iolock(vq, &buf->vb, NULL);
749 if (rc < 0)
750 goto fail;
751 }
752
753 buf->vb.state = VIDEOBUF_PREPARED;
754 return 0;
755fail:
756 free_buffer(vq, buf);
757 return rc;
758}
759
760static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
761{
762 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
763 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300764 struct s2255_channel *channel = fh->channel;
765 struct s2255_dmaqueue *vidq = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300766 dprintk(1, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300767 buf->vb.state = VIDEOBUF_QUEUED;
768 list_add_tail(&buf->vb.queue, &vidq->active);
769}
770
771static void buffer_release(struct videobuf_queue *vq,
772 struct videobuf_buffer *vb)
773{
774 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
775 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300776 dprintk(4, "%s %d\n", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -0300777 free_buffer(vq, buf);
778}
779
780static struct videobuf_queue_ops s2255_video_qops = {
781 .buf_setup = buffer_setup,
782 .buf_prepare = buffer_prepare,
783 .buf_queue = buffer_queue,
784 .buf_release = buffer_release,
785};
786
787
Dean Andersonfe85ce92010-06-01 19:12:07 -0300788static int res_get(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300789{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300790 struct s2255_channel *channel = fh->channel;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300791 /* is it free? */
792 if (channel->resources)
793 return 0; /* no, someone else uses it */
Dean Anderson38f993a2008-06-26 23:15:51 -0300794 /* it's free, grab it */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300795 channel->resources = 1;
796 fh->resources = 1;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300797 dprintk(1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300798 return 1;
799}
800
Dean Andersonfe85ce92010-06-01 19:12:07 -0300801static int res_locked(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300802{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300803 return fh->channel->resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300804}
805
Dean Andersonf78d92c2008-07-22 14:43:27 -0300806static int res_check(struct s2255_fh *fh)
807{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300808 return fh->resources;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300809}
810
811
Dean Andersonfe85ce92010-06-01 19:12:07 -0300812static void res_free(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300813{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300814 struct s2255_channel *channel = fh->channel;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300815 channel->resources = 0;
816 fh->resources = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300817 dprintk(1, "res: put\n");
818}
819
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300820static int vidioc_querymenu(struct file *file, void *priv,
821 struct v4l2_querymenu *qmenu)
822{
823 static const char *colorfilter[] = {
824 "Off",
825 "On",
826 NULL
827 };
828 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
829 int i;
830 const char **menu_items = colorfilter;
831 for (i = 0; i < qmenu->index && menu_items[i]; i++)
832 ; /* do nothing (from v4l2-common.c) */
833 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
834 return -EINVAL;
835 strlcpy(qmenu->name, menu_items[qmenu->index],
836 sizeof(qmenu->name));
837 return 0;
838 }
839 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
840}
841
Dean Anderson38f993a2008-06-26 23:15:51 -0300842static int vidioc_querycap(struct file *file, void *priv,
843 struct v4l2_capability *cap)
844{
845 struct s2255_fh *fh = file->private_data;
846 struct s2255_dev *dev = fh->dev;
847 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
848 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300849 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Dean Anderson38f993a2008-06-26 23:15:51 -0300850 cap->version = S2255_VERSION;
851 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
852 return 0;
853}
854
855static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
856 struct v4l2_fmtdesc *f)
857{
858 int index = 0;
859 if (f)
860 index = f->index;
861
862 if (index >= ARRAY_SIZE(formats))
863 return -EINVAL;
864
865 dprintk(4, "name %s\n", formats[index].name);
866 strlcpy(f->description, formats[index].name, sizeof(f->description));
867 f->pixelformat = formats[index].fourcc;
868 return 0;
869}
870
871static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
872 struct v4l2_format *f)
873{
874 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300875 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300876
Dean Andersonfe85ce92010-06-01 19:12:07 -0300877 f->fmt.pix.width = channel->width;
878 f->fmt.pix.height = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300879 f->fmt.pix.field = fh->vb_vidq.field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300880 f->fmt.pix.pixelformat = channel->fmt->fourcc;
881 f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300882 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300883 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300884}
885
886static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
887 struct v4l2_format *f)
888{
889 const struct s2255_fmt *fmt;
890 enum v4l2_field field;
891 int b_any_field = 0;
892 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300893 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300894 int is_ntsc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300895 is_ntsc =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300896 (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300897
898 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
899
900 if (fmt == NULL)
901 return -EINVAL;
902
903 field = f->fmt.pix.field;
904 if (field == V4L2_FIELD_ANY)
905 b_any_field = 1;
906
Dean Anderson85b85482010-04-08 23:51:17 -0300907 dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
908 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300909 if (is_ntsc) {
910 /* NTSC */
911 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
912 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
913 if (b_any_field) {
914 field = V4L2_FIELD_SEQ_TB;
915 } else if (!((field == V4L2_FIELD_INTERLACED) ||
916 (field == V4L2_FIELD_SEQ_TB) ||
917 (field == V4L2_FIELD_INTERLACED_TB))) {
918 dprintk(1, "unsupported field setting\n");
919 return -EINVAL;
920 }
921 } else {
922 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
923 if (b_any_field) {
924 field = V4L2_FIELD_TOP;
925 } else if (!((field == V4L2_FIELD_TOP) ||
926 (field == V4L2_FIELD_BOTTOM))) {
927 dprintk(1, "unsupported field setting\n");
928 return -EINVAL;
929 }
930
931 }
932 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
933 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
934 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
935 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
936 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
937 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
938 else
939 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
940 } else {
941 /* PAL */
942 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
943 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
944 if (b_any_field) {
945 field = V4L2_FIELD_SEQ_TB;
946 } else if (!((field == V4L2_FIELD_INTERLACED) ||
947 (field == V4L2_FIELD_SEQ_TB) ||
948 (field == V4L2_FIELD_INTERLACED_TB))) {
949 dprintk(1, "unsupported field setting\n");
950 return -EINVAL;
951 }
952 } else {
953 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
954 if (b_any_field) {
955 field = V4L2_FIELD_TOP;
956 } else if (!((field == V4L2_FIELD_TOP) ||
957 (field == V4L2_FIELD_BOTTOM))) {
958 dprintk(1, "unsupported field setting\n");
959 return -EINVAL;
960 }
961 }
962 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300963 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
964 field = V4L2_FIELD_SEQ_TB;
965 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300966 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
967 field = V4L2_FIELD_TOP;
968 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300969 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
970 field = V4L2_FIELD_TOP;
971 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300972 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
973 field = V4L2_FIELD_TOP;
974 }
975 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300976 f->fmt.pix.field = field;
977 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
978 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson85b85482010-04-08 23:51:17 -0300979 dprintk(50, "%s: set width %d height %d field %d\n", __func__,
980 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300981 return 0;
982}
983
984static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
985 struct v4l2_format *f)
986{
987 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300988 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300989 const struct s2255_fmt *fmt;
990 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300991 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300992 int ret;
993 int norm;
994
995 ret = vidioc_try_fmt_vid_cap(file, fh, f);
996
997 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300998 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300999
1000 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1001
1002 if (fmt == NULL)
1003 return -EINVAL;
1004
1005 mutex_lock(&q->vb_lock);
1006
1007 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1008 dprintk(1, "queue busy\n");
1009 ret = -EBUSY;
1010 goto out_s_fmt;
1011 }
1012
Dean Andersonfe85ce92010-06-01 19:12:07 -03001013 if (res_locked(fh)) {
Dean Anderson85b85482010-04-08 23:51:17 -03001014 dprintk(1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001015 ret = -EBUSY;
1016 goto out_s_fmt;
1017 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001018 mode = channel->mode;
1019 channel->fmt = fmt;
1020 channel->width = f->fmt.pix.width;
1021 channel->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -03001022 fh->vb_vidq.field = f->fmt.pix.field;
1023 fh->type = f->type;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001024 norm = norm_minw(&channel->vdev);
1025 if (channel->width > norm_minw(&channel->vdev)) {
1026 if (channel->height > norm_minh(&channel->vdev)) {
1027 if (channel->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -03001028 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001029 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -03001030 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001031 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -03001032 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001033 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001034
1035 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001036 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001037 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001038 /* color mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001039 switch (channel->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001040 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001041 mode.color &= ~MASK_COLOR;
1042 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001043 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001044 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -03001045 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001046 mode.color &= ~MASK_COLOR;
1047 mode.color |= COLOR_JPG;
1048 mode.color |= (channel->jc.quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001049 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001050 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001051 mode.color &= ~MASK_COLOR;
1052 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001053 break;
1054 case V4L2_PIX_FMT_YUYV:
1055 case V4L2_PIX_FMT_UYVY:
1056 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001057 mode.color &= ~MASK_COLOR;
1058 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001059 break;
1060 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001061 if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
1062 mode.restart = 1;
1063 else if (mode.scale != channel->mode.scale)
1064 mode.restart = 1;
1065 else if (mode.format != channel->mode.format)
1066 mode.restart = 1;
1067 channel->mode = mode;
1068 (void) s2255_set_mode(channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001069 ret = 0;
1070out_s_fmt:
1071 mutex_unlock(&q->vb_lock);
1072 return ret;
1073}
1074
1075static int vidioc_reqbufs(struct file *file, void *priv,
1076 struct v4l2_requestbuffers *p)
1077{
1078 int rc;
1079 struct s2255_fh *fh = priv;
1080 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1081 return rc;
1082}
1083
1084static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1085{
1086 int rc;
1087 struct s2255_fh *fh = priv;
1088 rc = videobuf_querybuf(&fh->vb_vidq, p);
1089 return rc;
1090}
1091
1092static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1093{
1094 int rc;
1095 struct s2255_fh *fh = priv;
1096 rc = videobuf_qbuf(&fh->vb_vidq, p);
1097 return rc;
1098}
1099
1100static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1101{
1102 int rc;
1103 struct s2255_fh *fh = priv;
1104 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1105 return rc;
1106}
1107
Dean Anderson38f993a2008-06-26 23:15:51 -03001108/* write to the configuration pipe, synchronously */
1109static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1110 int size)
1111{
1112 int pipe;
1113 int done;
1114 long retval = -1;
1115 if (udev) {
1116 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1117 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1118 }
1119 return retval;
1120}
1121
1122static u32 get_transfer_size(struct s2255_mode *mode)
1123{
1124 int linesPerFrame = LINE_SZ_DEF;
1125 int pixelsPerLine = NUM_LINES_DEF;
1126 u32 outImageSize;
1127 u32 usbInSize;
1128 unsigned int mask_mult;
1129
1130 if (mode == NULL)
1131 return 0;
1132
1133 if (mode->format == FORMAT_NTSC) {
1134 switch (mode->scale) {
1135 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001136 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001137 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1138 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1139 break;
1140 case SCALE_2CIFS:
1141 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1142 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1143 break;
1144 case SCALE_1CIFS:
1145 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1146 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1147 break;
1148 default:
1149 break;
1150 }
1151 } else if (mode->format == FORMAT_PAL) {
1152 switch (mode->scale) {
1153 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001154 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001155 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1156 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1157 break;
1158 case SCALE_2CIFS:
1159 linesPerFrame = NUM_LINES_2CIFS_PAL;
1160 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1161 break;
1162 case SCALE_1CIFS:
1163 linesPerFrame = NUM_LINES_1CIFS_PAL;
1164 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1165 break;
1166 default:
1167 break;
1168 }
1169 }
1170 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001171 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001172 /* 2 bytes/pixel if not monochrome */
1173 outImageSize *= 2;
1174 }
1175
1176 /* total bytes to send including prefix and 4K padding;
1177 must be a multiple of USB_READ_SIZE */
1178 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1179 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1180 /* if size not a multiple of USB_READ_SIZE */
1181 if (usbInSize & ~mask_mult)
1182 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1183 return usbInSize;
1184}
1185
Dean Anderson85b85482010-04-08 23:51:17 -03001186static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001187{
1188 struct device *dev = &sdev->udev->dev;
1189 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001190 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1191 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001192 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001193 dev_info(dev, "------------------------------------------------\n");
1194}
1195
1196/*
1197 * set mode is the function which controls the DSP.
1198 * the restart parameter in struct s2255_mode should be set whenever
1199 * the image size could change via color format, video system or image
1200 * size.
1201 * When the restart parameter is set, we sleep for ONE frame to allow the
1202 * DSP time to get the new frame
1203 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001204static int s2255_set_mode(struct s2255_channel *channel,
Dean Anderson38f993a2008-06-26 23:15:51 -03001205 struct s2255_mode *mode)
1206{
1207 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001208 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001209 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001210 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001211 chn_rev = G_chnmap[channel->idx];
1212 dprintk(3, "%s channel: %d\n", __func__, channel->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001213 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001214 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1215 mode->color &= ~MASK_COLOR;
1216 mode->color |= COLOR_JPG;
1217 mode->color &= ~MASK_JPG_QUALITY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001218 mode->color |= (channel->jc.quality << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001219 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001220 /* save the mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001221 channel->mode = *mode;
1222 channel->req_image_size = get_transfer_size(mode);
1223 dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001224 buffer = kzalloc(512, GFP_KERNEL);
1225 if (buffer == NULL) {
1226 dev_err(&dev->udev->dev, "out of mem\n");
1227 return -ENOMEM;
1228 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001229 /* set the mode */
1230 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001231 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001232 buffer[2] = CMD_SET_MODE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001233 memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
1234 channel->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001235 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1236 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001237 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001238 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001239 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001240 if (mode->restart) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001241 wait_event_timeout(channel->wait_setmode,
1242 (channel->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001243 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001244 if (channel->setmode_ready != 1) {
Dean Anderson14d96262008-08-25 13:58:55 -03001245 printk(KERN_DEBUG "s2255: no set mode response\n");
1246 res = -EFAULT;
1247 }
1248 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001249 /* clear the restart flag */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001250 channel->mode.restart = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001251 dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001252 return res;
1253}
1254
Dean Andersonfe85ce92010-06-01 19:12:07 -03001255static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001256{
1257 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001258 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001259 u32 chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001260 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001261 chn_rev = G_chnmap[channel->idx];
1262 dprintk(4, "%s chan %d\n", __func__, channel->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001263 buffer = kzalloc(512, GFP_KERNEL);
1264 if (buffer == NULL) {
1265 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001266 return -ENOMEM;
1267 }
1268 /* form the get vid status command */
1269 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001270 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001271 buffer[2] = CMD_STATUS;
1272 *pstatus = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001273 channel->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001274 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1275 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001276 wait_event_timeout(channel->wait_vidstatus,
1277 (channel->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001278 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001279 if (channel->vidstatus_ready != 1) {
Dean Anderson4de39f52010-03-03 19:39:19 -03001280 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1281 res = -EFAULT;
1282 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001283 *pstatus = channel->vidstatus;
Dean Anderson4de39f52010-03-03 19:39:19 -03001284 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03001285 return res;
1286}
1287
Dean Anderson38f993a2008-06-26 23:15:51 -03001288static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1289{
1290 int res;
1291 struct s2255_fh *fh = priv;
1292 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001293 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001294 int j;
1295 dprintk(4, "%s\n", __func__);
1296 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1297 dev_err(&dev->udev->dev, "invalid fh type0\n");
1298 return -EINVAL;
1299 }
1300 if (i != fh->type) {
1301 dev_err(&dev->udev->dev, "invalid fh type1\n");
1302 return -EINVAL;
1303 }
1304
Dean Andersonfe85ce92010-06-01 19:12:07 -03001305 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001306 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001307 return -EBUSY;
1308 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001309 channel->last_frame = -1;
1310 channel->bad_payload = 0;
1311 channel->cur_frame = 0;
1312 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001313 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001314 channel->buffer.frame[j].ulState = S2255_READ_IDLE;
1315 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001316 }
1317 res = videobuf_streamon(&fh->vb_vidq);
1318 if (res == 0) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001319 s2255_start_acquire(channel);
1320 channel->b_acquire = 1;
1321 } else
1322 res_free(fh);
1323
Dean Anderson38f993a2008-06-26 23:15:51 -03001324 return res;
1325}
1326
1327static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1328{
Dean Anderson38f993a2008-06-26 23:15:51 -03001329 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001330 dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001331 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1332 printk(KERN_ERR "invalid fh type0\n");
1333 return -EINVAL;
1334 }
1335 if (i != fh->type) {
1336 printk(KERN_ERR "invalid type i\n");
1337 return -EINVAL;
1338 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001339 s2255_stop_acquire(fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001340 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001341 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001342 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001343}
1344
1345static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1346{
1347 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001348 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001349 struct videobuf_queue *q = &fh->vb_vidq;
1350 int ret = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001351 mutex_lock(&q->vb_lock);
1352 if (videobuf_queue_is_busy(q)) {
1353 dprintk(1, "queue busy\n");
1354 ret = -EBUSY;
1355 goto out_s_std;
1356 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001357 if (res_locked(fh)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001358 dprintk(1, "can't change standard after started\n");
1359 ret = -EBUSY;
1360 goto out_s_std;
1361 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001362 mode = fh->channel->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001363 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001364 dprintk(4, "%s NTSC\n", __func__);
1365 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001366 if (mode.format != FORMAT_NTSC) {
1367 mode.restart = 1;
1368 mode.format = FORMAT_NTSC;
1369 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001370 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001371 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001372 dprintk(4, "%s PAL\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001373 if (mode.format != FORMAT_PAL) {
1374 mode.restart = 1;
1375 mode.format = FORMAT_PAL;
1376 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001377 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001378 } else {
1379 ret = -EINVAL;
1380 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001381 if (mode.restart)
1382 s2255_set_mode(fh->channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001383out_s_std:
1384 mutex_unlock(&q->vb_lock);
1385 return ret;
1386}
1387
1388/* Sensoray 2255 is a multiple channel capture device.
1389 It does not have a "crossbar" of inputs.
1390 We use one V4L device per channel. The user must
1391 be aware that certain combinations are not allowed.
1392 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1393 at once in color(you can do full fps on 4 channels with greyscale.
1394*/
1395static int vidioc_enum_input(struct file *file, void *priv,
1396 struct v4l2_input *inp)
1397{
Dean Anderson4de39f52010-03-03 19:39:19 -03001398 struct s2255_fh *fh = priv;
1399 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001400 struct s2255_channel *channel = fh->channel;
Dean Anderson4de39f52010-03-03 19:39:19 -03001401 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001402 if (inp->index != 0)
1403 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001404 inp->type = V4L2_INPUT_TYPE_CAMERA;
1405 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001406 inp->status = 0;
1407 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1408 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001409 rc = s2255_cmd_status(fh->channel, &status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001410 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1411 if (rc == 0)
1412 inp->status = (status & 0x01) ? 0
1413 : V4L2_IN_ST_NO_SIGNAL;
1414 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001415 switch (dev->pid) {
1416 case 0x2255:
1417 default:
1418 strlcpy(inp->name, "Composite", sizeof(inp->name));
1419 break;
1420 case 0x2257:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001421 strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001422 sizeof(inp->name));
1423 break;
1424 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001425 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001426}
1427
1428static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1429{
1430 *i = 0;
1431 return 0;
1432}
1433static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1434{
1435 if (i > 0)
1436 return -EINVAL;
1437 return 0;
1438}
1439
1440/* --- controls ---------------------------------------------- */
1441static int vidioc_queryctrl(struct file *file, void *priv,
1442 struct v4l2_queryctrl *qc)
1443{
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001444 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001445 struct s2255_channel *channel = fh->channel;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001446 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001447 switch (qc->id) {
1448 case V4L2_CID_BRIGHTNESS:
1449 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1450 break;
1451 case V4L2_CID_CONTRAST:
1452 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1453 break;
1454 case V4L2_CID_SATURATION:
1455 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1456 break;
1457 case V4L2_CID_HUE:
1458 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1459 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001460 case V4L2_CID_PRIVATE_COLORFILTER:
1461 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1462 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001463 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001464 return -EINVAL;
1465 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1466 qc->type = V4L2_CTRL_TYPE_MENU;
1467 qc->minimum = 0;
1468 qc->maximum = 1;
1469 qc->step = 1;
1470 qc->default_value = 1;
1471 qc->flags = 0;
1472 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001473 default:
1474 return -EINVAL;
1475 }
1476 dprintk(4, "%s, id %d\n", __func__, qc->id);
1477 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001478}
1479
1480static int vidioc_g_ctrl(struct file *file, void *priv,
1481 struct v4l2_control *ctrl)
1482{
Dean Anderson2e70db92010-03-05 14:29:09 -03001483 struct s2255_fh *fh = priv;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001484 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001485 struct s2255_channel *channel = fh->channel;
Dean Anderson2e70db92010-03-05 14:29:09 -03001486 switch (ctrl->id) {
1487 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001488 ctrl->value = channel->mode.bright;
Dean Anderson2e70db92010-03-05 14:29:09 -03001489 break;
1490 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001491 ctrl->value = channel->mode.contrast;
Dean Anderson2e70db92010-03-05 14:29:09 -03001492 break;
1493 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001494 ctrl->value = channel->mode.saturation;
Dean Anderson2e70db92010-03-05 14:29:09 -03001495 break;
1496 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001497 ctrl->value = channel->mode.hue;
Dean Anderson2e70db92010-03-05 14:29:09 -03001498 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001499 case V4L2_CID_PRIVATE_COLORFILTER:
1500 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1501 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001502 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001503 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001504 ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001505 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001506 default:
1507 return -EINVAL;
1508 }
1509 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1510 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001511}
1512
1513static int vidioc_s_ctrl(struct file *file, void *priv,
1514 struct v4l2_control *ctrl)
1515{
Dean Anderson38f993a2008-06-26 23:15:51 -03001516 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001517 struct s2255_channel *channel = fh->channel;
1518 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
1519 struct s2255_mode mode;
1520 mode = channel->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001521 dprintk(4, "%s\n", __func__);
1522 /* update the mode to the corresponding value */
1523 switch (ctrl->id) {
1524 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001525 mode.bright = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001526 break;
1527 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001528 mode.contrast = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001529 break;
1530 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001531 mode.hue = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001532 break;
1533 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001534 mode.saturation = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001535 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001536 case V4L2_CID_PRIVATE_COLORFILTER:
1537 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1538 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001539 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001540 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001541 mode.color &= ~MASK_INPUT_TYPE;
1542 mode.color |= ((ctrl->value ? 0 : 1) << 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001543 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001544 default:
1545 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001546 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001547 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001548 /* set mode here. Note: stream does not need restarted.
1549 some V4L programs restart stream unnecessarily
1550 after a s_crtl.
1551 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001552 s2255_set_mode(fh->channel, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001553 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001554}
1555
Dean Anderson22b88d42008-08-29 15:33:19 -03001556static int vidioc_g_jpegcomp(struct file *file, void *priv,
1557 struct v4l2_jpegcompression *jc)
1558{
1559 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001560 struct s2255_channel *channel = fh->channel;
1561 *jc = channel->jc;
Dean Anderson85b85482010-04-08 23:51:17 -03001562 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001563 return 0;
1564}
1565
1566static int vidioc_s_jpegcomp(struct file *file, void *priv,
1567 struct v4l2_jpegcompression *jc)
1568{
1569 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001570 struct s2255_channel *channel = fh->channel;
Dean Anderson22b88d42008-08-29 15:33:19 -03001571 if (jc->quality < 0 || jc->quality > 100)
1572 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001573 channel->jc.quality = jc->quality;
Dean Anderson85b85482010-04-08 23:51:17 -03001574 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001575 return 0;
1576}
Dean Anderson7d853532009-05-15 14:32:04 -03001577
1578static int vidioc_g_parm(struct file *file, void *priv,
1579 struct v4l2_streamparm *sp)
1580{
1581 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001582 __u32 def_num, def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001583 struct s2255_channel *channel = fh->channel;
Dean Anderson7d853532009-05-15 14:32:04 -03001584 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1585 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001586 memset(sp, 0, sizeof(struct v4l2_streamparm));
1587 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001588 sp->parm.capture.capturemode = channel->cap_parm.capturemode;
1589 def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1590 def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001591 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001592 switch (channel->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001593 default:
1594 case FDEC_1:
1595 sp->parm.capture.timeperframe.numerator = def_num;
1596 break;
1597 case FDEC_2:
1598 sp->parm.capture.timeperframe.numerator = def_num * 2;
1599 break;
1600 case FDEC_3:
1601 sp->parm.capture.timeperframe.numerator = def_num * 3;
1602 break;
1603 case FDEC_5:
1604 sp->parm.capture.timeperframe.numerator = def_num * 5;
1605 break;
1606 }
1607 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1608 sp->parm.capture.capturemode,
1609 sp->parm.capture.timeperframe.numerator,
1610 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001611 return 0;
1612}
1613
1614static int vidioc_s_parm(struct file *file, void *priv,
1615 struct v4l2_streamparm *sp)
1616{
1617 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001618 struct s2255_channel *channel = fh->channel;
1619 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001620 int fdec = FDEC_1;
1621 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001622 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1623 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001624 mode = channel->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001625 /* high quality capture mode requires a stream restart */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001626 if (channel->cap_parm.capturemode
1627 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001628 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001629 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1630 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001631 if (def_dem != sp->parm.capture.timeperframe.denominator)
1632 sp->parm.capture.timeperframe.numerator = def_num;
1633 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1634 sp->parm.capture.timeperframe.numerator = def_num;
1635 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1636 sp->parm.capture.timeperframe.numerator = def_num * 2;
1637 fdec = FDEC_2;
1638 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1639 sp->parm.capture.timeperframe.numerator = def_num * 3;
1640 fdec = FDEC_3;
1641 } else {
1642 sp->parm.capture.timeperframe.numerator = def_num * 5;
1643 fdec = FDEC_5;
1644 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001645 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001646 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001647 s2255_set_mode(channel, &mode);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001648 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1649 __func__,
1650 sp->parm.capture.capturemode,
1651 sp->parm.capture.timeperframe.numerator,
1652 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001653 return 0;
1654}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001655
1656static int vidioc_enum_frameintervals(struct file *file, void *priv,
1657 struct v4l2_frmivalenum *fe)
1658{
1659 int is_ntsc = 0;
1660#define NUM_FRAME_ENUMS 4
1661 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
1662 if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
1663 return -EINVAL;
1664 switch (fe->width) {
1665 case 640:
1666 if (fe->height != 240 && fe->height != 480)
1667 return -EINVAL;
1668 is_ntsc = 1;
1669 break;
1670 case 320:
1671 if (fe->height != 240)
1672 return -EINVAL;
1673 is_ntsc = 1;
1674 break;
1675 case 704:
1676 if (fe->height != 288 && fe->height != 576)
1677 return -EINVAL;
1678 break;
1679 case 352:
1680 if (fe->height != 288)
1681 return -EINVAL;
1682 break;
1683 default:
1684 return -EINVAL;
1685 }
1686 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1687 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1688 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1689 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1690 fe->discrete.denominator);
1691 return 0;
1692}
1693
Hans Verkuilbec43662008-12-30 06:58:20 -03001694static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001695{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001696 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001697 struct s2255_channel *channel = video_drvdata(file);
1698 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001699 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001700 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001701 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001702 dprintk(1, "s2255: open called (dev=%s)\n",
1703 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001704 /*
1705 * open lock necessary to prevent multiple instances
1706 * of v4l-conf (or other programs) from simultaneously
1707 * reloading firmware.
1708 */
Dean Anderson38f993a2008-06-26 23:15:51 -03001709 mutex_lock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001710 state = atomic_read(&dev->fw_data->fw_state);
1711 switch (state) {
1712 case S2255_FW_DISCONNECTING:
1713 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001714 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001715 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001716 s2255_dev_err(&dev->udev->dev,
1717 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001718 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001719 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001720 ((atomic_read(&dev->fw_data->fw_state)
1721 == S2255_FW_SUCCESS) ||
1722 (atomic_read(&dev->fw_data->fw_state)
1723 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001724 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001725 /* state may have changed, re-read */
1726 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001727 break;
1728 case S2255_FW_NOTLOADED:
1729 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001730 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1731 driver loaded and then device immediately opened */
1732 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1733 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001734 ((atomic_read(&dev->fw_data->fw_state)
1735 == S2255_FW_SUCCESS) ||
1736 (atomic_read(&dev->fw_data->fw_state)
1737 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001738 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001739 /* state may have changed, re-read */
1740 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001741 break;
1742 case S2255_FW_SUCCESS:
1743 default:
1744 break;
1745 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001746 /* state may have changed in above switch statement */
1747 switch (state) {
1748 case S2255_FW_SUCCESS:
1749 break;
1750 case S2255_FW_FAILED:
1751 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Andersoneb78dee2010-04-12 15:05:37 -03001752 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001753 return -ENODEV;
1754 case S2255_FW_DISCONNECTING:
1755 printk(KERN_INFO "%s: disconnecting\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001756 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001757 return -ENODEV;
1758 case S2255_FW_LOADED_DSPWAIT:
1759 case S2255_FW_NOTLOADED:
1760 printk(KERN_INFO "%s: firmware not loaded yet"
1761 "please try again later\n",
1762 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001763 /*
1764 * Timeout on firmware load means device unusable.
1765 * Set firmware failure state.
1766 * On next s2255_open the firmware will be reloaded.
1767 */
1768 atomic_set(&dev->fw_data->fw_state,
1769 S2255_FW_FAILED);
1770 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001771 return -EAGAIN;
1772 default:
1773 printk(KERN_INFO "%s: unknown state\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001774 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001775 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001776 }
Dean Andersoneb78dee2010-04-12 15:05:37 -03001777 mutex_unlock(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001778 /* allocate + initialize per filehandle data */
1779 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001780 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001781 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03001782 file->private_data = fh;
1783 fh->dev = dev;
1784 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001785 fh->channel = channel;
1786 if (!channel->configured) {
1787 /* configure channel to default state */
1788 channel->fmt = &formats[0];
1789 s2255_set_mode(channel, &channel->mode);
1790 channel->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001791 }
Dean Anderson85b85482010-04-08 23:51:17 -03001792 dprintk(1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001793 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson85b85482010-04-08 23:51:17 -03001794 dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001795 (unsigned long)fh, (unsigned long)dev,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001796 (unsigned long)&channel->vidq);
Dean Anderson85b85482010-04-08 23:51:17 -03001797 dprintk(4, "%s: list_empty active=%d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001798 list_empty(&channel->vidq.active));
Dean Anderson38f993a2008-06-26 23:15:51 -03001799 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1800 NULL, &dev->slock,
1801 fh->type,
1802 V4L2_FIELD_INTERLACED,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001803 sizeof(struct s2255_buffer),
1804 fh, vdev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001805 return 0;
1806}
1807
1808
1809static unsigned int s2255_poll(struct file *file,
1810 struct poll_table_struct *wait)
1811{
1812 struct s2255_fh *fh = file->private_data;
1813 int rc;
1814 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001815 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1816 return POLLERR;
Dean Anderson38f993a2008-06-26 23:15:51 -03001817 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
1818 return rc;
1819}
1820
Dean Andersond62e85a2010-04-09 19:54:26 -03001821static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001822{
Dean Anderson38f993a2008-06-26 23:15:51 -03001823 /* board shutdown stops the read pipe if it is running */
1824 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001825 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001826 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001827 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001828 usb_kill_urb(dev->fw_data->fw_urb);
1829 usb_free_urb(dev->fw_data->fw_urb);
1830 dev->fw_data->fw_urb = NULL;
1831 }
Dean Andersonf78d92c2008-07-22 14:43:27 -03001832 if (dev->fw_data->fw)
1833 release_firmware(dev->fw_data->fw);
1834 kfree(dev->fw_data->pfw_data);
1835 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001836 /* reset the DSP so firmware can be reloaded next time */
1837 s2255_reset_dsppower(dev);
1838 mutex_destroy(&dev->open_lock);
1839 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001840 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001841 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001842 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001843 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001844}
1845
Dean Andersonff7e22d2010-04-08 23:38:07 -03001846static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001847{
1848 struct s2255_fh *fh = file->private_data;
1849 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001850 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001851 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001852 if (!dev)
1853 return -ENODEV;
Dean Andersonf78d92c2008-07-22 14:43:27 -03001854 /* turn off stream */
1855 if (res_check(fh)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001856 if (channel->b_acquire)
1857 s2255_stop_acquire(fh->channel);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001858 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001859 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001860 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001861 videobuf_mmap_free(&fh->vb_vidq);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001862 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001863 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001864 return 0;
1865}
1866
1867static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1868{
1869 struct s2255_fh *fh = file->private_data;
1870 int ret;
1871
1872 if (!fh)
1873 return -ENODEV;
Dean Anderson85b85482010-04-08 23:51:17 -03001874 dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Dean Anderson38f993a2008-06-26 23:15:51 -03001875 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
Dean Anderson85b85482010-04-08 23:51:17 -03001876 dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001877 (unsigned long)vma->vm_start,
1878 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001879 return ret;
1880}
1881
Hans Verkuilbec43662008-12-30 06:58:20 -03001882static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001883 .owner = THIS_MODULE,
1884 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001885 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001886 .poll = s2255_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001887 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001888 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001889};
1890
Hans Verkuila3998102008-07-21 02:57:38 -03001891static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001892 .vidioc_querymenu = vidioc_querymenu,
Dean Anderson38f993a2008-06-26 23:15:51 -03001893 .vidioc_querycap = vidioc_querycap,
1894 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1895 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1896 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1897 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1898 .vidioc_reqbufs = vidioc_reqbufs,
1899 .vidioc_querybuf = vidioc_querybuf,
1900 .vidioc_qbuf = vidioc_qbuf,
1901 .vidioc_dqbuf = vidioc_dqbuf,
1902 .vidioc_s_std = vidioc_s_std,
1903 .vidioc_enum_input = vidioc_enum_input,
1904 .vidioc_g_input = vidioc_g_input,
1905 .vidioc_s_input = vidioc_s_input,
1906 .vidioc_queryctrl = vidioc_queryctrl,
1907 .vidioc_g_ctrl = vidioc_g_ctrl,
1908 .vidioc_s_ctrl = vidioc_s_ctrl,
1909 .vidioc_streamon = vidioc_streamon,
1910 .vidioc_streamoff = vidioc_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001911 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1912 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001913 .vidioc_s_parm = vidioc_s_parm,
1914 .vidioc_g_parm = vidioc_g_parm,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001915 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuila3998102008-07-21 02:57:38 -03001916};
1917
Dean Andersonff7e22d2010-04-08 23:38:07 -03001918static void s2255_video_device_release(struct video_device *vdev)
1919{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001920 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
1921 dprintk(4, "%s, chnls: %d \n", __func__,
1922 atomic_read(&dev->num_channels));
1923 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001924 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001925 return;
1926}
1927
Hans Verkuila3998102008-07-21 02:57:38 -03001928static struct video_device template = {
1929 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001930 .fops = &s2255_fops_v4l,
1931 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001932 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001933 .tvnorms = S2255_NORMS,
1934 .current_norm = V4L2_STD_NTSC_M,
1935};
1936
1937static int s2255_probe_v4l(struct s2255_dev *dev)
1938{
1939 int ret;
1940 int i;
1941 int cur_nr = video_nr;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001942 struct s2255_channel *channel;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001943 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1944 if (ret)
1945 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001946 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001947 /* register 4 video devices */
1948 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001949 channel = &dev->channel[i];
1950 INIT_LIST_HEAD(&channel->vidq.active);
1951 channel->vidq.dev = dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001952 /* register 4 video devices */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001953 channel->vdev = template;
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001954 channel->vdev.lock = &dev->lock;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001955 channel->vdev.v4l2_dev = &dev->v4l2_dev;
1956 video_set_drvdata(&channel->vdev, channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03001957 if (video_nr == -1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001958 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001959 VFL_TYPE_GRABBER,
1960 video_nr);
1961 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001962 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001963 VFL_TYPE_GRABBER,
1964 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001965
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001966 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001967 dev_err(&dev->udev->dev,
1968 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001969 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001970 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001971 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001972 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001973 video_device_node_name(&channel->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001974
Dean Anderson38f993a2008-06-26 23:15:51 -03001975 }
Dean Andersonabce21f2009-04-23 16:04:41 -03001976 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
1977 S2255_MAJOR_VERSION,
1978 S2255_MINOR_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001979 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001980 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001981 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001982 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001983 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001984 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001985 printk(KERN_WARNING "s2255: Not all channels available.\n");
1986 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001987}
1988
Dean Anderson38f993a2008-06-26 23:15:51 -03001989/* this function moves the usb stream read pipe data
1990 * into the system buffers.
1991 * returns 0 on success, EAGAIN if more data to process( call this
1992 * function again).
1993 *
1994 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001995 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001996 * bytes 4-7: channel: 0-3
1997 * bytes 8-11: payload size: size of the frame
1998 * bytes 12-payloadsize+12: frame data
1999 */
2000static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
2001{
Dean Anderson38f993a2008-06-26 23:15:51 -03002002 char *pdest;
2003 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002004 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002005 char *psrc;
2006 unsigned long copy_size;
2007 unsigned long size;
2008 s32 idx = -1;
2009 struct s2255_framei *frm;
2010 unsigned char *pdata;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002011 struct s2255_channel *channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03002012 dprintk(100, "buffer to user\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002013 channel = &dev->channel[dev->cc];
2014 idx = channel->cur_frame;
2015 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002016 if (frm->ulState == S2255_READ_IDLE) {
2017 int jj;
2018 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03002019 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03002020 int payload;
2021 /* search for marker codes */
2022 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03002023 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002024 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03002025 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03002026 case S2255_MARKER_FRAME:
Dean Anderson14d96262008-08-25 13:58:55 -03002027 dprintk(4, "found frame marker at offset:"
2028 " %d [%x %x]\n", jj, pdata[0],
2029 pdata[1]);
2030 offset = jj + PREFIX_SIZE;
2031 bframe = 1;
2032 cc = pdword[1];
2033 if (cc >= MAX_CHANNELS) {
2034 printk(KERN_ERR
2035 "bad channel\n");
2036 return -EINVAL;
2037 }
2038 /* reverse it */
2039 dev->cc = G_chnmap[cc];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002040 channel = &dev->channel[dev->cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002041 payload = pdword[3];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002042 if (payload > channel->req_image_size) {
2043 channel->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03002044 /* discard the bad frame */
2045 return -EINVAL;
2046 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002047 channel->pkt_size = payload;
2048 channel->jpg_size = pdword[4];
Dean Anderson14d96262008-08-25 13:58:55 -03002049 break;
2050 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002051
Dean Anderson14d96262008-08-25 13:58:55 -03002052 pdata += DEF_USB_BLOCK;
2053 jj += DEF_USB_BLOCK;
2054 if (pdword[1] >= MAX_CHANNELS)
2055 break;
2056 cc = G_chnmap[pdword[1]];
Roel Kluinf14a2972009-10-23 07:59:42 -03002057 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002058 break;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002059 channel = &dev->channel[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002060 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03002061 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03002062 /* check if channel valid */
2063 /* set mode ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002064 channel->setmode_ready = 1;
2065 wake_up(&channel->wait_setmode);
Dean Anderson14d96262008-08-25 13:58:55 -03002066 dprintk(5, "setmode ready %d\n", cc);
2067 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002068 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002069 dev->chn_ready |= (1 << cc);
2070 if ((dev->chn_ready & 0x0f) != 0x0f)
2071 break;
2072 /* all channels ready */
2073 printk(KERN_INFO "s2255: fw loaded\n");
2074 atomic_set(&dev->fw_data->fw_state,
2075 S2255_FW_SUCCESS);
2076 wake_up(&dev->fw_data->wait_fw);
2077 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002078 case S2255_RESPONSE_STATUS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002079 channel->vidstatus = pdword[3];
2080 channel->vidstatus_ready = 1;
2081 wake_up(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002082 dprintk(5, "got vidstatus %x chan %d\n",
2083 pdword[3], cc);
2084 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002085 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02002086 printk(KERN_INFO "s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002087 }
2088 default:
2089 pdata++;
2090 break;
2091 }
2092 if (bframe)
2093 break;
2094 } /* for */
2095 if (!bframe)
2096 return -EINVAL;
2097 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002098 channel = &dev->channel[dev->cc];
2099 idx = channel->cur_frame;
2100 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002101 /* search done. now find out if should be acquiring on this channel */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002102 if (!channel->b_acquire) {
Dean Anderson14d96262008-08-25 13:58:55 -03002103 /* we found a frame, but this channel is turned off */
2104 frm->ulState = S2255_READ_IDLE;
2105 return -EINVAL;
2106 }
2107
2108 if (frm->ulState == S2255_READ_IDLE) {
2109 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002110 frm->cur_size = 0;
2111 }
2112
Dean Anderson14d96262008-08-25 13:58:55 -03002113 /* skip the marker 512 bytes (and offset if out of sync) */
2114 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2115
Dean Anderson38f993a2008-06-26 23:15:51 -03002116
2117 if (frm->lpvbits == NULL) {
2118 dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
2119 frm, dev, dev->cc, idx);
2120 return -ENOMEM;
2121 }
2122
2123 pdest = frm->lpvbits + frm->cur_size;
2124
Dean Anderson14d96262008-08-25 13:58:55 -03002125 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002126
Dean Andersonfe85ce92010-06-01 19:12:07 -03002127 size = channel->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002128
Dean Anderson14d96262008-08-25 13:58:55 -03002129 /* sanity check on pdest */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002130 if ((copy_size + frm->cur_size) < channel->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03002131 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002132
Dean Anderson38f993a2008-06-26 23:15:51 -03002133 frm->cur_size += copy_size;
Dean Anderson14d96262008-08-25 13:58:55 -03002134 dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002135
Dean Anderson14d96262008-08-25 13:58:55 -03002136 if (frm->cur_size >= size) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002137 dprintk(2, "****************[%d]Buffer[%d]full*************\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002138 dev->cc, idx);
2139 channel->last_frame = channel->cur_frame;
2140 channel->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002141 /* end of system frame ring buffer, start at zero */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002142 if ((channel->cur_frame == SYS_FRAMES) ||
2143 (channel->cur_frame == channel->buffer.dwFrames))
2144 channel->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002145 /* frame ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002146 if (channel->b_acquire)
2147 s2255_got_frame(channel, channel->jpg_size);
2148 channel->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03002149 frm->ulState = S2255_READ_IDLE;
2150 frm->cur_size = 0;
2151
Dean Anderson38f993a2008-06-26 23:15:51 -03002152 }
2153 /* done successfully */
2154 return 0;
2155}
2156
2157static void s2255_read_video_callback(struct s2255_dev *dev,
2158 struct s2255_pipeinfo *pipe_info)
2159{
2160 int res;
2161 dprintk(50, "callback read video \n");
2162
2163 if (dev->cc >= MAX_CHANNELS) {
2164 dev->cc = 0;
2165 dev_err(&dev->udev->dev, "invalid channel\n");
2166 return;
2167 }
2168 /* otherwise copy to the system buffers */
2169 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002170 if (res != 0)
2171 dprintk(4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002172
2173 dprintk(50, "callback read video done\n");
2174 return;
2175}
2176
2177static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2178 u16 Index, u16 Value, void *TransferBuffer,
2179 s32 TransferBufferLength, int bOut)
2180{
2181 int r;
2182 if (!bOut) {
2183 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2184 Request,
2185 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2186 USB_DIR_IN,
2187 Value, Index, TransferBuffer,
2188 TransferBufferLength, HZ * 5);
2189 } else {
2190 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2191 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2192 Value, Index, TransferBuffer,
2193 TransferBufferLength, HZ * 5);
2194 }
2195 return r;
2196}
2197
2198/*
2199 * retrieve FX2 firmware version. future use.
2200 * @param dev pointer to device extension
2201 * @return -1 for fail, else returns firmware version as an int(16 bits)
2202 */
2203static int s2255_get_fx2fw(struct s2255_dev *dev)
2204{
2205 int fw;
2206 int ret;
2207 unsigned char transBuffer[64];
2208 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2209 S2255_VR_IN);
2210 if (ret < 0)
2211 dprintk(2, "get fw error: %x\n", ret);
2212 fw = transBuffer[0] + (transBuffer[1] << 8);
2213 dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
2214 return fw;
2215}
2216
2217/*
2218 * Create the system ring buffer to copy frames into from the
2219 * usb read pipe.
2220 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002221static int s2255_create_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002222{
2223 unsigned long i;
2224 unsigned long reqsize;
2225 dprintk(1, "create sys buffers\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002226 channel->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03002227 /* always allocate maximum size(PAL) for system buffers */
2228 reqsize = SYS_FRAMES_MAXSIZE;
2229
2230 if (reqsize > SYS_FRAMES_MAXSIZE)
2231 reqsize = SYS_FRAMES_MAXSIZE;
2232
2233 for (i = 0; i < SYS_FRAMES; i++) {
2234 /* allocate the frames */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002235 channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
2236 dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
2237 &channel->buffer.frame[i], channel->idx, i,
2238 channel->buffer.frame[i].lpvbits);
2239 channel->buffer.frame[i].size = reqsize;
2240 if (channel->buffer.frame[i].lpvbits == NULL) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002241 printk(KERN_INFO "out of memory. using less frames\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002242 channel->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002243 break;
2244 }
2245 }
2246
2247 /* make sure internal states are set */
2248 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002249 channel->buffer.frame[i].ulState = 0;
2250 channel->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002251 }
2252
Dean Andersonfe85ce92010-06-01 19:12:07 -03002253 channel->cur_frame = 0;
2254 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002255 return 0;
2256}
2257
Dean Andersonfe85ce92010-06-01 19:12:07 -03002258static int s2255_release_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002259{
2260 unsigned long i;
2261 dprintk(1, "release sys buffers\n");
2262 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002263 if (channel->buffer.frame[i].lpvbits) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002264 dprintk(1, "vfree %p\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002265 channel->buffer.frame[i].lpvbits);
2266 vfree(channel->buffer.frame[i].lpvbits);
Dean Anderson38f993a2008-06-26 23:15:51 -03002267 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002268 channel->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002269 }
2270 return 0;
2271}
2272
2273static int s2255_board_init(struct s2255_dev *dev)
2274{
Dean Anderson38f993a2008-06-26 23:15:51 -03002275 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2276 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002277 int j;
2278 struct s2255_pipeinfo *pipe = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002279 dprintk(4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002280 memset(pipe, 0, sizeof(*pipe));
2281 pipe->dev = dev;
2282 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2283 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002284
Dean Andersonab85c6a2010-04-08 23:39:12 -03002285 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2286 GFP_KERNEL);
2287 if (pipe->transfer_buffer == NULL) {
2288 dprintk(1, "out of memory!\n");
2289 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002290 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002291 /* query the firmware */
2292 fw_ver = s2255_get_fx2fw(dev);
2293
Dean Andersonabce21f2009-04-23 16:04:41 -03002294 printk(KERN_INFO "2255 usb firmware version %d.%d\n",
2295 (fw_ver >> 8) & 0xff,
2296 fw_ver & 0xff);
2297
2298 if (fw_ver < S2255_CUR_USB_FWVER)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002299 dev_err(&dev->udev->dev,
Dean Andersonabce21f2009-04-23 16:04:41 -03002300 "usb firmware not up to date %d.%d\n",
2301 (fw_ver >> 8) & 0xff,
2302 fw_ver & 0xff);
Dean Anderson38f993a2008-06-26 23:15:51 -03002303
2304 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002305 struct s2255_channel *channel = &dev->channel[j];
2306 channel->b_acquire = 0;
2307 channel->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002308 if (dev->pid == 0x2257 && j > 1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002309 channel->mode.color |= (1 << 16);
2310 channel->jc.quality = S2255_DEF_JPEG_QUAL;
2311 channel->width = LINE_SZ_4CIFS_NTSC;
2312 channel->height = NUM_LINES_4CIFS_NTSC * 2;
2313 channel->fmt = &formats[0];
2314 channel->mode.restart = 1;
2315 channel->req_image_size = get_transfer_size(&mode_def);
2316 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002317 /* create the system buffers */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002318 s2255_create_sys_buffers(channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03002319 }
2320 /* start read pipe */
2321 s2255_start_readpipe(dev);
Dean Anderson85b85482010-04-08 23:51:17 -03002322 dprintk(1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002323 return 0;
2324}
2325
2326static int s2255_board_shutdown(struct s2255_dev *dev)
2327{
2328 u32 i;
Dean Anderson85b85482010-04-08 23:51:17 -03002329 dprintk(1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002330
2331 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002332 if (dev->channel[i].b_acquire)
2333 s2255_stop_acquire(&dev->channel[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002334 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002335 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002336 for (i = 0; i < MAX_CHANNELS; i++)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002337 s2255_release_sys_buffers(&dev->channel[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002338 /* release transfer buffer */
2339 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002340 return 0;
2341}
2342
2343static void read_pipe_completion(struct urb *purb)
2344{
2345 struct s2255_pipeinfo *pipe_info;
2346 struct s2255_dev *dev;
2347 int status;
2348 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002349 pipe_info = purb->context;
Dean Anderson85b85482010-04-08 23:51:17 -03002350 dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
Dean Anderson38f993a2008-06-26 23:15:51 -03002351 purb->status);
2352 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002353 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002354 return;
2355 }
2356
2357 dev = pipe_info->dev;
2358 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002359 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002360 return;
2361 }
2362 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002363 /* if shutting down, do not resubmit, exit immediately */
2364 if (status == -ESHUTDOWN) {
Dean Anderson85b85482010-04-08 23:51:17 -03002365 dprintk(2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002366 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002367 return;
2368 }
2369
2370 if (pipe_info->state == 0) {
Dean Anderson85b85482010-04-08 23:51:17 -03002371 dprintk(2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002372 return;
2373 }
2374
Dean Andersonb02064c2009-04-30 12:29:38 -03002375 if (status == 0)
2376 s2255_read_video_callback(dev, pipe_info);
2377 else {
2378 pipe_info->err_count++;
Dean Anderson85b85482010-04-08 23:51:17 -03002379 dprintk(1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002380 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002381
Dean Anderson38f993a2008-06-26 23:15:51 -03002382 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2383 /* reuse urb */
2384 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2385 pipe,
2386 pipe_info->transfer_buffer,
2387 pipe_info->cur_transfer_size,
2388 read_pipe_completion, pipe_info);
2389
2390 if (pipe_info->state != 0) {
Pete Eberleina1b4c862011-04-01 21:21:26 -03002391 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002392 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002393 }
2394 } else {
Dean Anderson85b85482010-04-08 23:51:17 -03002395 dprintk(2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002396 }
2397 return;
2398}
2399
2400static int s2255_start_readpipe(struct s2255_dev *dev)
2401{
2402 int pipe;
2403 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002404 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002405 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
Dean Anderson85b85482010-04-08 23:51:17 -03002406 dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002407 pipe_info->state = 1;
2408 pipe_info->err_count = 0;
2409 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2410 if (!pipe_info->stream_urb) {
2411 dev_err(&dev->udev->dev,
2412 "ReadStream: Unable to alloc URB\n");
2413 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002414 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002415 /* transfer buffer allocated in board_init */
2416 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2417 pipe,
2418 pipe_info->transfer_buffer,
2419 pipe_info->cur_transfer_size,
2420 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002421 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2422 if (retval) {
2423 printk(KERN_ERR "s2255: start read pipe failed\n");
2424 return retval;
2425 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002426 return 0;
2427}
2428
2429/* starts acquisition process */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002430static int s2255_start_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002431{
2432 unsigned char *buffer;
2433 int res;
2434 unsigned long chn_rev;
2435 int j;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002436 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2437 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002438 buffer = kzalloc(512, GFP_KERNEL);
2439 if (buffer == NULL) {
2440 dev_err(&dev->udev->dev, "out of mem\n");
2441 return -ENOMEM;
2442 }
2443
Dean Andersonfe85ce92010-06-01 19:12:07 -03002444 channel->last_frame = -1;
2445 channel->bad_payload = 0;
2446 channel->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002447 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002448 channel->buffer.frame[j].ulState = 0;
2449 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002450 }
2451
2452 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002453 *(__le32 *) buffer = IN_DATA_TOKEN;
2454 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2455 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002456 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2457 if (res != 0)
2458 dev_err(&dev->udev->dev, "CMD_START error\n");
2459
Dean Andersonfe85ce92010-06-01 19:12:07 -03002460 dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03002461 kfree(buffer);
2462 return 0;
2463}
2464
Dean Andersonfe85ce92010-06-01 19:12:07 -03002465static int s2255_stop_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002466{
2467 unsigned char *buffer;
2468 int res;
2469 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002470 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2471 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002472 buffer = kzalloc(512, GFP_KERNEL);
2473 if (buffer == NULL) {
2474 dev_err(&dev->udev->dev, "out of mem\n");
2475 return -ENOMEM;
2476 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002477 /* send the stop command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002478 *(__le32 *) buffer = IN_DATA_TOKEN;
2479 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2480 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002481 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002482 if (res != 0)
2483 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002484 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002485 channel->b_acquire = 0;
2486 dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
Dean Anderson14d96262008-08-25 13:58:55 -03002487 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002488}
2489
2490static void s2255_stop_readpipe(struct s2255_dev *dev)
2491{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002492 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002493
Dean Andersonab85c6a2010-04-08 23:39:12 -03002494 pipe->state = 0;
2495 if (pipe->stream_urb) {
2496 /* cancel urb */
2497 usb_kill_urb(pipe->stream_urb);
2498 usb_free_urb(pipe->stream_urb);
2499 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002500 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002501 dprintk(4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002502 return;
2503}
2504
Dean Anderson14d96262008-08-25 13:58:55 -03002505static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002506{
Dean Anderson14d96262008-08-25 13:58:55 -03002507 if (reset)
2508 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002509 dev->fw_data->fw_size = dev->fw_data->fw->size;
2510 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2511 memcpy(dev->fw_data->pfw_data,
2512 dev->fw_data->fw->data, CHUNK_SIZE);
2513 dev->fw_data->fw_loaded = CHUNK_SIZE;
2514 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2515 usb_sndbulkpipe(dev->udev, 2),
2516 dev->fw_data->pfw_data,
2517 CHUNK_SIZE, s2255_fwchunk_complete,
2518 dev->fw_data);
2519 mod_timer(&dev->timer, jiffies + HZ);
2520}
2521
2522/* standard usb probe function */
2523static int s2255_probe(struct usb_interface *interface,
2524 const struct usb_device_id *id)
2525{
2526 struct s2255_dev *dev = NULL;
2527 struct usb_host_interface *iface_desc;
2528 struct usb_endpoint_descriptor *endpoint;
2529 int i;
2530 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002531 __le32 *pdata;
2532 int fw_size;
Dean Anderson85b85482010-04-08 23:51:17 -03002533 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002534 /* allocate memory for our device state and initialize it to zero */
2535 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2536 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002537 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002538 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002539 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002540 atomic_set(&dev->num_channels, 0);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002541 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002542 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2543 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002544 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002545 mutex_init(&dev->lock);
2546 mutex_init(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002547 /* grab usb_device and save it */
2548 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2549 if (dev->udev == NULL) {
2550 dev_err(&interface->dev, "null usb device\n");
2551 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002552 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002553 }
Dean Andersond62e85a2010-04-09 19:54:26 -03002554 dprintk(1, "dev: %p, udev %p interface %p\n", dev,
Dean Anderson38f993a2008-06-26 23:15:51 -03002555 dev->udev, interface);
2556 dev->interface = interface;
2557 /* set up the endpoint information */
2558 iface_desc = interface->cur_altsetting;
2559 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2560 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2561 endpoint = &iface_desc->endpoint[i].desc;
2562 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2563 /* we found the bulk in endpoint */
2564 dev->read_endpoint = endpoint->bEndpointAddress;
2565 }
2566 }
2567
2568 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002569 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002570 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002571 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002572 init_timer(&dev->timer);
2573 dev->timer.function = s2255_timer;
2574 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002575 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002576 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002577 struct s2255_channel *channel = &dev->channel[i];
2578 dev->channel[i].idx = i;
2579 init_waitqueue_head(&channel->wait_setmode);
2580 init_waitqueue_head(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002581 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002582
2583 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002584 if (!dev->fw_data->fw_urb) {
2585 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002586 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002587 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002588
Dean Anderson38f993a2008-06-26 23:15:51 -03002589 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2590 if (!dev->fw_data->pfw_data) {
2591 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002592 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002593 }
2594 /* load the first chunk */
2595 if (request_firmware(&dev->fw_data->fw,
2596 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2597 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002598 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002599 }
Dean Anderson14d96262008-08-25 13:58:55 -03002600 /* check the firmware is valid */
2601 fw_size = dev->fw_data->fw->size;
2602 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002603
Dean Anderson14d96262008-08-25 13:58:55 -03002604 if (*pdata != S2255_FW_MARKER) {
2605 printk(KERN_INFO "Firmware invalid.\n");
2606 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002607 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002608 } else {
2609 /* make sure firmware is the latest */
2610 __le32 *pRel;
2611 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2612 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dean Anderson4de39f52010-03-03 19:39:19 -03002613 dev->dsp_fw_ver = *pRel;
2614 if (*pRel < S2255_CUR_DSP_FWVER)
2615 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002616 if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002617 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
Dean Andersonfe85ce92010-06-01 19:12:07 -03002618 " or above.\n", S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002619 }
Dean Anderson14d96262008-08-25 13:58:55 -03002620 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002621 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002622 retval = s2255_board_init(dev);
2623 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002624 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002625 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002626 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002627 /* loads v4l specific */
2628 retval = s2255_probe_v4l(dev);
2629 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002630 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002631 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2632 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002633errorBOARDINIT:
2634 s2255_board_shutdown(dev);
2635errorFWMARKER:
2636 release_firmware(dev->fw_data->fw);
2637errorREQFW:
2638 kfree(dev->fw_data->pfw_data);
2639errorFWDATA2:
2640 usb_free_urb(dev->fw_data->fw_urb);
2641errorFWURB:
2642 del_timer(&dev->timer);
2643errorEP:
2644 usb_put_dev(dev->udev);
2645errorUDEV:
2646 kfree(dev->fw_data);
2647 mutex_destroy(&dev->open_lock);
2648 mutex_destroy(&dev->lock);
2649errorFWDATA1:
2650 kfree(dev);
2651 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002652 return retval;
2653}
2654
2655/* disconnect routine. when board is removed physically or with rmmod */
2656static void s2255_disconnect(struct usb_interface *interface)
2657{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002658 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002659 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002660 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002661 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002662 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002663 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002664 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002665 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002666 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002667 for (i = 0; i < channels; i++)
2668 video_unregister_device(&dev->channel[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002669 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002670 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2671 wake_up(&dev->fw_data->wait_fw);
2672 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002673 dev->channel[i].setmode_ready = 1;
2674 wake_up(&dev->channel[i].wait_setmode);
2675 dev->channel[i].vidstatus_ready = 1;
2676 wake_up(&dev->channel[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002677 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002678 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002679 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002680 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002681}
2682
2683static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002684 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002685 .probe = s2255_probe,
2686 .disconnect = s2255_disconnect,
2687 .id_table = s2255_table,
2688};
2689
2690static int __init usb_s2255_init(void)
2691{
2692 int result;
Dean Anderson38f993a2008-06-26 23:15:51 -03002693 /* register this driver with the USB subsystem */
2694 result = usb_register(&s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002695 if (result)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002696 pr_err(KBUILD_MODNAME
Dean Andersonff7e22d2010-04-08 23:38:07 -03002697 ": usb_register failed. Error number %d\n", result);
2698 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002699 return result;
2700}
2701
2702static void __exit usb_s2255_exit(void)
2703{
2704 usb_deregister(&s2255_driver);
2705}
2706
2707module_init(usb_s2255_init);
2708module_exit(usb_s2255_exit);
2709
2710MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2711MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2712MODULE_LICENSE("GPL");