blob: cf03372d1d1706dd16968b3886385bc8039159ee [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
Dean Andersoneb78dee2010-04-12 15:05:37 -030060#define S2255_MINOR_VERSION 20
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 */
315#define S2255_CUR_USB_FWVER ((3 << 8) | 6)
Dean Anderson4de39f52010-03-03 19:39:19 -0300316/* current DSP FW version */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300317#define S2255_CUR_DSP_FWVER 8
Dean Anderson4de39f52010-03-03 19:39:19 -0300318/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300319#define S2255_MIN_DSP_STATUS 5
320#define S2255_MIN_DSP_COLORFILTER 8
Dean Anderson38f993a2008-06-26 23:15:51 -0300321#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300322
323/* private V4L2 controls */
324
325/*
326 * The following chart displays how COLORFILTER should be set
327 * =========================================================
328 * = fourcc = COLORFILTER =
329 * = ===============================
330 * = = 0 = 1 =
331 * =========================================================
332 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
333 * = = s-video or = composite =
334 * = = B/W camera = input =
335 * =========================================================
336 * = other = color, svideo = color, =
337 * = = = composite =
338 * =========================================================
339 *
340 * Notes:
341 * channels 0-3 on 2255 are composite
342 * channels 0-1 on 2257 are composite, 2-3 are s-video
343 * If COLORFILTER is 0 with a composite color camera connected,
344 * the output will appear monochrome but hatching
345 * will occur.
346 * COLORFILTER is different from "color killer" and "color effects"
347 * for reasons above.
348 */
349#define S2255_V4L2_YC_ON 1
350#define S2255_V4L2_YC_OFF 0
351#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
352
Dean Anderson38f993a2008-06-26 23:15:51 -0300353/* frame prefix size (sent once every frame) */
354#define PREFIX_SIZE 512
355
356/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300357static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300358
Dean Anderson38f993a2008-06-26 23:15:51 -0300359static int debug;
360static int *s2255_debug = &debug;
361
362static int s2255_start_readpipe(struct s2255_dev *dev);
363static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300364static int s2255_start_acquire(struct s2255_channel *channel);
365static int s2255_stop_acquire(struct s2255_channel *channel);
366static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
367 int jpgsize);
368static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300369static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300370static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300371static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300372static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
373 u16 index, u16 value, void *buf,
374 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300375
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300376/* dev_err macro with driver name */
377#define S2255_DRIVER_NAME "s2255"
378#define s2255_dev_err(dev, fmt, arg...) \
379 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
380
Dean Anderson38f993a2008-06-26 23:15:51 -0300381#define dprintk(level, fmt, arg...) \
382 do { \
383 if (*s2255_debug >= (level)) { \
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300384 printk(KERN_DEBUG S2255_DRIVER_NAME \
385 ": " fmt, ##arg); \
Dean Anderson38f993a2008-06-26 23:15:51 -0300386 } \
387 } while (0)
388
Dean Anderson38f993a2008-06-26 23:15:51 -0300389static struct usb_driver s2255_driver;
390
Dean Anderson38f993a2008-06-26 23:15:51 -0300391/* Declare static vars that will be used as parameters */
392static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
393
394/* start video number */
395static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
396
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300397module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300398MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300399module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300400MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300401module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300402MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
403
404/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300405#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300406static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300407 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
408 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300409 { } /* Terminating entry */
410};
411MODULE_DEVICE_TABLE(usb, s2255_table);
412
Dean Anderson38f993a2008-06-26 23:15:51 -0300413#define BUFFER_TIMEOUT msecs_to_jiffies(400)
414
Dean Anderson38f993a2008-06-26 23:15:51 -0300415/* image formats. */
416static const struct s2255_fmt formats[] = {
417 {
418 .name = "4:2:2, planar, YUV422P",
419 .fourcc = V4L2_PIX_FMT_YUV422P,
420 .depth = 16
421
422 }, {
423 .name = "4:2:2, packed, YUYV",
424 .fourcc = V4L2_PIX_FMT_YUYV,
425 .depth = 16
426
427 }, {
428 .name = "4:2:2, packed, UYVY",
429 .fourcc = V4L2_PIX_FMT_UYVY,
430 .depth = 16
431 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300432 .name = "JPG",
433 .fourcc = V4L2_PIX_FMT_JPEG,
434 .depth = 24
435 }, {
Dean Anderson38f993a2008-06-26 23:15:51 -0300436 .name = "8bpp GREY",
437 .fourcc = V4L2_PIX_FMT_GREY,
438 .depth = 8
439 }
440};
441
442static int norm_maxw(struct video_device *vdev)
443{
444 return (vdev->current_norm & V4L2_STD_NTSC) ?
445 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
446}
447
448static int norm_maxh(struct video_device *vdev)
449{
450 return (vdev->current_norm & V4L2_STD_NTSC) ?
451 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
452}
453
454static int norm_minw(struct video_device *vdev)
455{
456 return (vdev->current_norm & V4L2_STD_NTSC) ?
457 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
458}
459
460static int norm_minh(struct video_device *vdev)
461{
462 return (vdev->current_norm & V4L2_STD_NTSC) ?
463 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
464}
465
466
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300467/*
468 * TODO: fixme: move YUV reordering to hardware
469 * converts 2255 planar format to yuyv or uyvy
470 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300471static void planar422p_to_yuv_packed(const unsigned char *in,
472 unsigned char *out,
473 int width, int height,
474 int fmt)
475{
476 unsigned char *pY;
477 unsigned char *pCb;
478 unsigned char *pCr;
479 unsigned long size = height * width;
480 unsigned int i;
481 pY = (unsigned char *)in;
482 pCr = (unsigned char *)in + height * width;
483 pCb = (unsigned char *)in + height * width + (height * width / 2);
484 for (i = 0; i < size * 2; i += 4) {
485 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
486 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
487 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
488 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
489 }
490 return;
491}
492
Hans Verkuild45b9b82008-09-04 03:33:43 -0300493static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300494{
495 s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b0b, NULL, 0, 1);
496 msleep(10);
497 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
498 return;
499}
Dean Anderson38f993a2008-06-26 23:15:51 -0300500
501/* kickstarts the firmware loading. from probe
502 */
503static void s2255_timer(unsigned long user_data)
504{
505 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson85b85482010-04-08 23:51:17 -0300506 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300507 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
508 printk(KERN_ERR "s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300509 atomic_set(&data->fw_state, S2255_FW_FAILED);
510 /* wake up anything waiting for the firmware */
511 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300512 return;
513 }
514}
515
Dean Anderson38f993a2008-06-26 23:15:51 -0300516
517/* this loads the firmware asynchronously.
518 Originally this was done synchroously in probe.
519 But it is better to load it asynchronously here than block
520 inside the probe function. Blocking inside probe affects boot time.
521 FW loading is triggered by the timer in the probe function
522*/
523static void s2255_fwchunk_complete(struct urb *urb)
524{
525 struct s2255_fw *data = urb->context;
526 struct usb_device *udev = urb->dev;
527 int len;
Dean Anderson85b85482010-04-08 23:51:17 -0300528 dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
Dean Anderson38f993a2008-06-26 23:15:51 -0300529 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300530 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300531 atomic_set(&data->fw_state, S2255_FW_FAILED);
532 /* wake up anything waiting for the firmware */
533 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300534 return;
535 }
536 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300537 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300538 atomic_set(&data->fw_state, S2255_FW_FAILED);
539 /* wake up anything waiting for the firmware */
540 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300541 return;
542 }
543#define CHUNK_SIZE 512
544 /* all USB transfers must be done with continuous kernel memory.
545 can't allocate more than 128k in current linux kernel, so
546 upload the firmware in chunks
547 */
548 if (data->fw_loaded < data->fw_size) {
549 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
550 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
551
552 if (len < CHUNK_SIZE)
553 memset(data->pfw_data, 0, CHUNK_SIZE);
554
555 dprintk(100, "completed len %d, loaded %d \n", len,
556 data->fw_loaded);
557
558 memcpy(data->pfw_data,
559 (char *) data->fw->data + data->fw_loaded, len);
560
561 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
562 data->pfw_data, CHUNK_SIZE,
563 s2255_fwchunk_complete, data);
564 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
565 dev_err(&udev->dev, "failed submit URB\n");
566 atomic_set(&data->fw_state, S2255_FW_FAILED);
567 /* wake up anything waiting for the firmware */
568 wake_up(&data->wait_fw);
569 return;
570 }
571 data->fw_loaded += len;
572 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300573 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson85b85482010-04-08 23:51:17 -0300574 dprintk(100, "%s: firmware upload complete\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300575 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300576 return;
577
578}
579
Dean Andersonfe85ce92010-06-01 19:12:07 -0300580static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300581{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300582 struct s2255_dmaqueue *dma_q = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300583 struct s2255_buffer *buf;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300584 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300585 unsigned long flags = 0;
586 int rc = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300587 spin_lock_irqsave(&dev->slock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300588 if (list_empty(&dma_q->active)) {
589 dprintk(1, "No active queue to serve\n");
590 rc = -1;
591 goto unlock;
592 }
593 buf = list_entry(dma_q->active.next,
594 struct s2255_buffer, vb.queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300595 list_del(&buf->vb.queue);
596 do_gettimeofday(&buf->vb.ts);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300597 s2255_fillbuff(channel, buf, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300598 wake_up(&buf->vb.done);
Dean Anderson85b85482010-04-08 23:51:17 -0300599 dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
Dean Anderson38f993a2008-06-26 23:15:51 -0300600unlock:
601 spin_unlock_irqrestore(&dev->slock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300602 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300603}
604
Dean Anderson38f993a2008-06-26 23:15:51 -0300605static const struct s2255_fmt *format_by_fourcc(int fourcc)
606{
607 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300608 for (i = 0; i < ARRAY_SIZE(formats); i++) {
609 if (-1 == formats[i].fourcc)
610 continue;
611 if (formats[i].fourcc == fourcc)
612 return formats + i;
613 }
614 return NULL;
615}
616
Dean Anderson38f993a2008-06-26 23:15:51 -0300617/* video buffer vmalloc implementation based partly on VIVI driver which is
618 * Copyright (c) 2006 by
619 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
620 * Ted Walther <ted--a.t--enumera.com>
621 * John Sokol <sokol--a.t--videotechnology.com>
622 * http://v4l.videotechnology.com/
623 *
624 */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300625static void s2255_fillbuff(struct s2255_channel *channel,
626 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300627{
628 int pos = 0;
629 struct timeval ts;
630 const char *tmpbuf;
631 char *vbuf = videobuf_to_vmalloc(&buf->vb);
632 unsigned long last_frame;
633 struct s2255_framei *frm;
634
635 if (!vbuf)
636 return;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300637 last_frame = channel->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300638 if (last_frame != -1) {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300639 frm = &channel->buffer.frame[last_frame];
Dean Anderson38f993a2008-06-26 23:15:51 -0300640 tmpbuf =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300641 (const char *)channel->buffer.frame[last_frame].lpvbits;
Dean Anderson38f993a2008-06-26 23:15:51 -0300642 switch (buf->fmt->fourcc) {
643 case V4L2_PIX_FMT_YUYV:
644 case V4L2_PIX_FMT_UYVY:
645 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
646 vbuf, buf->vb.width,
647 buf->vb.height,
648 buf->fmt->fourcc);
649 break;
650 case V4L2_PIX_FMT_GREY:
651 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
652 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300653 case V4L2_PIX_FMT_JPEG:
654 buf->vb.size = jpgsize;
655 memcpy(vbuf, tmpbuf, buf->vb.size);
656 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300657 case V4L2_PIX_FMT_YUV422P:
658 memcpy(vbuf, tmpbuf,
659 buf->vb.width * buf->vb.height * 2);
660 break;
661 default:
662 printk(KERN_DEBUG "s2255: unknown format?\n");
663 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300664 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300665 } else {
666 printk(KERN_ERR "s2255: =======no frame\n");
667 return;
668
669 }
670 dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
671 (unsigned long)vbuf, pos);
672 /* tell v4l buffer was filled */
673
Dean Andersonfe85ce92010-06-01 19:12:07 -0300674 buf->vb.field_count = channel->frame_count * 2;
Dean Anderson38f993a2008-06-26 23:15:51 -0300675 do_gettimeofday(&ts);
676 buf->vb.ts = ts;
677 buf->vb.state = VIDEOBUF_DONE;
678}
679
680
681/* ------------------------------------------------------------------
682 Videobuf operations
683 ------------------------------------------------------------------*/
684
685static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
686 unsigned int *size)
687{
688 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300689 struct s2255_channel *channel = fh->channel;
690 *size = channel->width * channel->height * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300691
692 if (0 == *count)
693 *count = S2255_DEF_BUFS;
694
Andreas Bombedab7e312010-03-21 16:02:45 -0300695 if (*size * *count > vid_limit * 1024 * 1024)
696 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300697
698 return 0;
699}
700
701static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
702{
703 dprintk(4, "%s\n", __func__);
704
Dean Anderson38f993a2008-06-26 23:15:51 -0300705 videobuf_vmalloc_free(&buf->vb);
706 buf->vb.state = VIDEOBUF_NEEDS_INIT;
707}
708
709static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
710 enum v4l2_field field)
711{
712 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300713 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300714 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
715 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300716 int w = channel->width;
717 int h = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300718 dprintk(4, "%s, field=%d\n", __func__, field);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300719 if (channel->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300720 return -EINVAL;
721
Dean Andersonfe85ce92010-06-01 19:12:07 -0300722 if ((w < norm_minw(&channel->vdev)) ||
723 (w > norm_maxw(&channel->vdev)) ||
724 (h < norm_minh(&channel->vdev)) ||
725 (h > norm_maxh(&channel->vdev))) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300726 dprintk(4, "invalid buffer prepare\n");
727 return -EINVAL;
728 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300729 buf->vb.size = w * h * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300730 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
731 dprintk(4, "invalid buffer prepare\n");
732 return -EINVAL;
733 }
734
Dean Andersonfe85ce92010-06-01 19:12:07 -0300735 buf->fmt = channel->fmt;
736 buf->vb.width = w;
737 buf->vb.height = h;
Dean Anderson38f993a2008-06-26 23:15:51 -0300738 buf->vb.field = field;
739
Dean Anderson38f993a2008-06-26 23:15:51 -0300740 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
741 rc = videobuf_iolock(vq, &buf->vb, NULL);
742 if (rc < 0)
743 goto fail;
744 }
745
746 buf->vb.state = VIDEOBUF_PREPARED;
747 return 0;
748fail:
749 free_buffer(vq, buf);
750 return rc;
751}
752
753static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
754{
755 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
756 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300757 struct s2255_channel *channel = fh->channel;
758 struct s2255_dmaqueue *vidq = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300759 dprintk(1, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300760 buf->vb.state = VIDEOBUF_QUEUED;
761 list_add_tail(&buf->vb.queue, &vidq->active);
762}
763
764static void buffer_release(struct videobuf_queue *vq,
765 struct videobuf_buffer *vb)
766{
767 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
768 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300769 dprintk(4, "%s %d\n", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -0300770 free_buffer(vq, buf);
771}
772
773static struct videobuf_queue_ops s2255_video_qops = {
774 .buf_setup = buffer_setup,
775 .buf_prepare = buffer_prepare,
776 .buf_queue = buffer_queue,
777 .buf_release = buffer_release,
778};
779
780
Dean Andersonfe85ce92010-06-01 19:12:07 -0300781static int res_get(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300782{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300783 struct s2255_channel *channel = fh->channel;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300784 /* is it free? */
785 if (channel->resources)
786 return 0; /* no, someone else uses it */
Dean Anderson38f993a2008-06-26 23:15:51 -0300787 /* it's free, grab it */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300788 channel->resources = 1;
789 fh->resources = 1;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300790 dprintk(1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300791 return 1;
792}
793
Dean Andersonfe85ce92010-06-01 19:12:07 -0300794static int res_locked(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300795{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300796 return fh->channel->resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300797}
798
Dean Andersonf78d92c2008-07-22 14:43:27 -0300799static int res_check(struct s2255_fh *fh)
800{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300801 return fh->resources;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300802}
803
804
Dean Andersonfe85ce92010-06-01 19:12:07 -0300805static void res_free(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300806{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300807 struct s2255_channel *channel = fh->channel;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300808 channel->resources = 0;
809 fh->resources = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300810 dprintk(1, "res: put\n");
811}
812
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300813static int vidioc_querymenu(struct file *file, void *priv,
814 struct v4l2_querymenu *qmenu)
815{
816 static const char *colorfilter[] = {
817 "Off",
818 "On",
819 NULL
820 };
821 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
822 int i;
823 const char **menu_items = colorfilter;
824 for (i = 0; i < qmenu->index && menu_items[i]; i++)
825 ; /* do nothing (from v4l2-common.c) */
826 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
827 return -EINVAL;
828 strlcpy(qmenu->name, menu_items[qmenu->index],
829 sizeof(qmenu->name));
830 return 0;
831 }
832 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
833}
834
Dean Anderson38f993a2008-06-26 23:15:51 -0300835static int vidioc_querycap(struct file *file, void *priv,
836 struct v4l2_capability *cap)
837{
838 struct s2255_fh *fh = file->private_data;
839 struct s2255_dev *dev = fh->dev;
840 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
841 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300842 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Dean Anderson38f993a2008-06-26 23:15:51 -0300843 cap->version = S2255_VERSION;
844 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
845 return 0;
846}
847
848static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
849 struct v4l2_fmtdesc *f)
850{
851 int index = 0;
852 if (f)
853 index = f->index;
854
855 if (index >= ARRAY_SIZE(formats))
856 return -EINVAL;
857
858 dprintk(4, "name %s\n", formats[index].name);
859 strlcpy(f->description, formats[index].name, sizeof(f->description));
860 f->pixelformat = formats[index].fourcc;
861 return 0;
862}
863
864static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
865 struct v4l2_format *f)
866{
867 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300868 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300869
Dean Andersonfe85ce92010-06-01 19:12:07 -0300870 f->fmt.pix.width = channel->width;
871 f->fmt.pix.height = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300872 f->fmt.pix.field = fh->vb_vidq.field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300873 f->fmt.pix.pixelformat = channel->fmt->fourcc;
874 f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300875 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300876 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300877}
878
879static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
880 struct v4l2_format *f)
881{
882 const struct s2255_fmt *fmt;
883 enum v4l2_field field;
884 int b_any_field = 0;
885 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300886 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300887 int is_ntsc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300888 is_ntsc =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300889 (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300890
891 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
892
893 if (fmt == NULL)
894 return -EINVAL;
895
896 field = f->fmt.pix.field;
897 if (field == V4L2_FIELD_ANY)
898 b_any_field = 1;
899
Dean Anderson85b85482010-04-08 23:51:17 -0300900 dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
901 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300902 if (is_ntsc) {
903 /* NTSC */
904 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
905 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
906 if (b_any_field) {
907 field = V4L2_FIELD_SEQ_TB;
908 } else if (!((field == V4L2_FIELD_INTERLACED) ||
909 (field == V4L2_FIELD_SEQ_TB) ||
910 (field == V4L2_FIELD_INTERLACED_TB))) {
911 dprintk(1, "unsupported field setting\n");
912 return -EINVAL;
913 }
914 } else {
915 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
916 if (b_any_field) {
917 field = V4L2_FIELD_TOP;
918 } else if (!((field == V4L2_FIELD_TOP) ||
919 (field == V4L2_FIELD_BOTTOM))) {
920 dprintk(1, "unsupported field setting\n");
921 return -EINVAL;
922 }
923
924 }
925 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
926 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
927 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
928 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
929 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
930 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
931 else
932 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
933 } else {
934 /* PAL */
935 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
936 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
937 if (b_any_field) {
938 field = V4L2_FIELD_SEQ_TB;
939 } else if (!((field == V4L2_FIELD_INTERLACED) ||
940 (field == V4L2_FIELD_SEQ_TB) ||
941 (field == V4L2_FIELD_INTERLACED_TB))) {
942 dprintk(1, "unsupported field setting\n");
943 return -EINVAL;
944 }
945 } else {
946 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
947 if (b_any_field) {
948 field = V4L2_FIELD_TOP;
949 } else if (!((field == V4L2_FIELD_TOP) ||
950 (field == V4L2_FIELD_BOTTOM))) {
951 dprintk(1, "unsupported field setting\n");
952 return -EINVAL;
953 }
954 }
955 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300956 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
957 field = V4L2_FIELD_SEQ_TB;
958 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300959 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
960 field = V4L2_FIELD_TOP;
961 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300962 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
963 field = V4L2_FIELD_TOP;
964 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300965 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
966 field = V4L2_FIELD_TOP;
967 }
968 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300969 f->fmt.pix.field = field;
970 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
971 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson85b85482010-04-08 23:51:17 -0300972 dprintk(50, "%s: set width %d height %d field %d\n", __func__,
973 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300974 return 0;
975}
976
977static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
978 struct v4l2_format *f)
979{
980 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300981 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300982 const struct s2255_fmt *fmt;
983 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300984 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300985 int ret;
986 int norm;
987
988 ret = vidioc_try_fmt_vid_cap(file, fh, f);
989
990 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300991 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300992
993 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
994
995 if (fmt == NULL)
996 return -EINVAL;
997
998 mutex_lock(&q->vb_lock);
999
1000 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1001 dprintk(1, "queue busy\n");
1002 ret = -EBUSY;
1003 goto out_s_fmt;
1004 }
1005
Dean Andersonfe85ce92010-06-01 19:12:07 -03001006 if (res_locked(fh)) {
Dean Anderson85b85482010-04-08 23:51:17 -03001007 dprintk(1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001008 ret = -EBUSY;
1009 goto out_s_fmt;
1010 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001011 mode = channel->mode;
1012 channel->fmt = fmt;
1013 channel->width = f->fmt.pix.width;
1014 channel->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -03001015 fh->vb_vidq.field = f->fmt.pix.field;
1016 fh->type = f->type;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001017 norm = norm_minw(&channel->vdev);
1018 if (channel->width > norm_minw(&channel->vdev)) {
1019 if (channel->height > norm_minh(&channel->vdev)) {
1020 if (channel->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -03001021 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001022 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -03001023 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001024 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -03001025 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001026 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001027
1028 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001029 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001030 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001031 /* color mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001032 switch (channel->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001033 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001034 mode.color &= ~MASK_COLOR;
1035 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001036 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001037 case V4L2_PIX_FMT_JPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001038 mode.color &= ~MASK_COLOR;
1039 mode.color |= COLOR_JPG;
1040 mode.color |= (channel->jc.quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001041 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001042 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001043 mode.color &= ~MASK_COLOR;
1044 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001045 break;
1046 case V4L2_PIX_FMT_YUYV:
1047 case V4L2_PIX_FMT_UYVY:
1048 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001049 mode.color &= ~MASK_COLOR;
1050 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001051 break;
1052 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001053 if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
1054 mode.restart = 1;
1055 else if (mode.scale != channel->mode.scale)
1056 mode.restart = 1;
1057 else if (mode.format != channel->mode.format)
1058 mode.restart = 1;
1059 channel->mode = mode;
1060 (void) s2255_set_mode(channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001061 ret = 0;
1062out_s_fmt:
1063 mutex_unlock(&q->vb_lock);
1064 return ret;
1065}
1066
1067static int vidioc_reqbufs(struct file *file, void *priv,
1068 struct v4l2_requestbuffers *p)
1069{
1070 int rc;
1071 struct s2255_fh *fh = priv;
1072 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1073 return rc;
1074}
1075
1076static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1077{
1078 int rc;
1079 struct s2255_fh *fh = priv;
1080 rc = videobuf_querybuf(&fh->vb_vidq, p);
1081 return rc;
1082}
1083
1084static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1085{
1086 int rc;
1087 struct s2255_fh *fh = priv;
1088 rc = videobuf_qbuf(&fh->vb_vidq, p);
1089 return rc;
1090}
1091
1092static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1093{
1094 int rc;
1095 struct s2255_fh *fh = priv;
1096 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1097 return rc;
1098}
1099
1100#ifdef CONFIG_VIDEO_V4L1_COMPAT
1101static int vidioc_cgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1102{
1103 struct s2255_fh *fh = priv;
1104
1105 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
1106}
1107#endif
1108
1109/* write to the configuration pipe, synchronously */
1110static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1111 int size)
1112{
1113 int pipe;
1114 int done;
1115 long retval = -1;
1116 if (udev) {
1117 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1118 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1119 }
1120 return retval;
1121}
1122
1123static u32 get_transfer_size(struct s2255_mode *mode)
1124{
1125 int linesPerFrame = LINE_SZ_DEF;
1126 int pixelsPerLine = NUM_LINES_DEF;
1127 u32 outImageSize;
1128 u32 usbInSize;
1129 unsigned int mask_mult;
1130
1131 if (mode == NULL)
1132 return 0;
1133
1134 if (mode->format == FORMAT_NTSC) {
1135 switch (mode->scale) {
1136 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001137 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001138 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1139 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1140 break;
1141 case SCALE_2CIFS:
1142 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1143 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1144 break;
1145 case SCALE_1CIFS:
1146 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1147 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1148 break;
1149 default:
1150 break;
1151 }
1152 } else if (mode->format == FORMAT_PAL) {
1153 switch (mode->scale) {
1154 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001155 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001156 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1157 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1158 break;
1159 case SCALE_2CIFS:
1160 linesPerFrame = NUM_LINES_2CIFS_PAL;
1161 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1162 break;
1163 case SCALE_1CIFS:
1164 linesPerFrame = NUM_LINES_1CIFS_PAL;
1165 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1166 break;
1167 default:
1168 break;
1169 }
1170 }
1171 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001172 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001173 /* 2 bytes/pixel if not monochrome */
1174 outImageSize *= 2;
1175 }
1176
1177 /* total bytes to send including prefix and 4K padding;
1178 must be a multiple of USB_READ_SIZE */
1179 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1180 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1181 /* if size not a multiple of USB_READ_SIZE */
1182 if (usbInSize & ~mask_mult)
1183 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1184 return usbInSize;
1185}
1186
Dean Anderson85b85482010-04-08 23:51:17 -03001187static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001188{
1189 struct device *dev = &sdev->udev->dev;
1190 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001191 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1192 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001193 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001194 dev_info(dev, "------------------------------------------------\n");
1195}
1196
1197/*
1198 * set mode is the function which controls the DSP.
1199 * the restart parameter in struct s2255_mode should be set whenever
1200 * the image size could change via color format, video system or image
1201 * size.
1202 * When the restart parameter is set, we sleep for ONE frame to allow the
1203 * DSP time to get the new frame
1204 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001205static int s2255_set_mode(struct s2255_channel *channel,
Dean Anderson38f993a2008-06-26 23:15:51 -03001206 struct s2255_mode *mode)
1207{
1208 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001209 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001210 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001211 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001212 chn_rev = G_chnmap[channel->idx];
1213 dprintk(3, "%s channel: %d\n", __func__, channel->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001214 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001215 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1216 mode->color &= ~MASK_COLOR;
1217 mode->color |= COLOR_JPG;
1218 mode->color &= ~MASK_JPG_QUALITY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001219 mode->color |= (channel->jc.quality << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001220 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001221 /* save the mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001222 channel->mode = *mode;
1223 channel->req_image_size = get_transfer_size(mode);
1224 dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001225 buffer = kzalloc(512, GFP_KERNEL);
1226 if (buffer == NULL) {
1227 dev_err(&dev->udev->dev, "out of mem\n");
1228 return -ENOMEM;
1229 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001230 /* set the mode */
1231 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001232 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001233 buffer[2] = CMD_SET_MODE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001234 memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
1235 channel->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001236 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1237 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001238 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001239 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001240 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001241 if (mode->restart) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001242 wait_event_timeout(channel->wait_setmode,
1243 (channel->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001244 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001245 if (channel->setmode_ready != 1) {
Dean Anderson14d96262008-08-25 13:58:55 -03001246 printk(KERN_DEBUG "s2255: no set mode response\n");
1247 res = -EFAULT;
1248 }
1249 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001250 /* clear the restart flag */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001251 channel->mode.restart = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001252 dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001253 return res;
1254}
1255
Dean Andersonfe85ce92010-06-01 19:12:07 -03001256static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001257{
1258 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001259 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001260 u32 chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001261 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001262 chn_rev = G_chnmap[channel->idx];
1263 dprintk(4, "%s chan %d\n", __func__, channel->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001264 buffer = kzalloc(512, GFP_KERNEL);
1265 if (buffer == NULL) {
1266 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001267 return -ENOMEM;
1268 }
1269 /* form the get vid status command */
1270 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001271 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001272 buffer[2] = CMD_STATUS;
1273 *pstatus = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001274 channel->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001275 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1276 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001277 wait_event_timeout(channel->wait_vidstatus,
1278 (channel->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001279 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001280 if (channel->vidstatus_ready != 1) {
Dean Anderson4de39f52010-03-03 19:39:19 -03001281 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1282 res = -EFAULT;
1283 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001284 *pstatus = channel->vidstatus;
Dean Anderson4de39f52010-03-03 19:39:19 -03001285 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03001286 return res;
1287}
1288
Dean Anderson38f993a2008-06-26 23:15:51 -03001289static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1290{
1291 int res;
1292 struct s2255_fh *fh = priv;
1293 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001294 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001295 int j;
1296 dprintk(4, "%s\n", __func__);
1297 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1298 dev_err(&dev->udev->dev, "invalid fh type0\n");
1299 return -EINVAL;
1300 }
1301 if (i != fh->type) {
1302 dev_err(&dev->udev->dev, "invalid fh type1\n");
1303 return -EINVAL;
1304 }
1305
Dean Andersonfe85ce92010-06-01 19:12:07 -03001306 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001307 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001308 return -EBUSY;
1309 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001310 channel->last_frame = -1;
1311 channel->bad_payload = 0;
1312 channel->cur_frame = 0;
1313 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001314 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001315 channel->buffer.frame[j].ulState = S2255_READ_IDLE;
1316 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001317 }
1318 res = videobuf_streamon(&fh->vb_vidq);
1319 if (res == 0) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001320 s2255_start_acquire(channel);
1321 channel->b_acquire = 1;
1322 } else
1323 res_free(fh);
1324
Dean Anderson38f993a2008-06-26 23:15:51 -03001325 return res;
1326}
1327
1328static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1329{
Dean Anderson38f993a2008-06-26 23:15:51 -03001330 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001331 dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001332 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1333 printk(KERN_ERR "invalid fh type0\n");
1334 return -EINVAL;
1335 }
1336 if (i != fh->type) {
1337 printk(KERN_ERR "invalid type i\n");
1338 return -EINVAL;
1339 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001340 s2255_stop_acquire(fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001341 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001342 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001343 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001344}
1345
1346static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1347{
1348 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001349 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001350 struct videobuf_queue *q = &fh->vb_vidq;
1351 int ret = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001352 mutex_lock(&q->vb_lock);
1353 if (videobuf_queue_is_busy(q)) {
1354 dprintk(1, "queue busy\n");
1355 ret = -EBUSY;
1356 goto out_s_std;
1357 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001358 if (res_locked(fh)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001359 dprintk(1, "can't change standard after started\n");
1360 ret = -EBUSY;
1361 goto out_s_std;
1362 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001363 mode = fh->channel->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001364 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001365 dprintk(4, "%s NTSC\n", __func__);
1366 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001367 if (mode.format != FORMAT_NTSC) {
1368 mode.restart = 1;
1369 mode.format = FORMAT_NTSC;
1370 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001371 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001372 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001373 dprintk(4, "%s PAL\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001374 if (mode.format != FORMAT_PAL) {
1375 mode.restart = 1;
1376 mode.format = FORMAT_PAL;
1377 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001378 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001379 } else {
1380 ret = -EINVAL;
1381 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001382 if (mode.restart)
1383 s2255_set_mode(fh->channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001384out_s_std:
1385 mutex_unlock(&q->vb_lock);
1386 return ret;
1387}
1388
1389/* Sensoray 2255 is a multiple channel capture device.
1390 It does not have a "crossbar" of inputs.
1391 We use one V4L device per channel. The user must
1392 be aware that certain combinations are not allowed.
1393 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1394 at once in color(you can do full fps on 4 channels with greyscale.
1395*/
1396static int vidioc_enum_input(struct file *file, void *priv,
1397 struct v4l2_input *inp)
1398{
Dean Anderson4de39f52010-03-03 19:39:19 -03001399 struct s2255_fh *fh = priv;
1400 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001401 struct s2255_channel *channel = fh->channel;
Dean Anderson4de39f52010-03-03 19:39:19 -03001402 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001403 if (inp->index != 0)
1404 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001405 inp->type = V4L2_INPUT_TYPE_CAMERA;
1406 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001407 inp->status = 0;
1408 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1409 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001410 rc = s2255_cmd_status(fh->channel, &status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001411 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1412 if (rc == 0)
1413 inp->status = (status & 0x01) ? 0
1414 : V4L2_IN_ST_NO_SIGNAL;
1415 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001416 switch (dev->pid) {
1417 case 0x2255:
1418 default:
1419 strlcpy(inp->name, "Composite", sizeof(inp->name));
1420 break;
1421 case 0x2257:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001422 strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001423 sizeof(inp->name));
1424 break;
1425 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001426 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001427}
1428
1429static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1430{
1431 *i = 0;
1432 return 0;
1433}
1434static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1435{
1436 if (i > 0)
1437 return -EINVAL;
1438 return 0;
1439}
1440
1441/* --- controls ---------------------------------------------- */
1442static int vidioc_queryctrl(struct file *file, void *priv,
1443 struct v4l2_queryctrl *qc)
1444{
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001445 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001446 struct s2255_channel *channel = fh->channel;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001447 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001448 switch (qc->id) {
1449 case V4L2_CID_BRIGHTNESS:
1450 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1451 break;
1452 case V4L2_CID_CONTRAST:
1453 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1454 break;
1455 case V4L2_CID_SATURATION:
1456 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1457 break;
1458 case V4L2_CID_HUE:
1459 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1460 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001461 case V4L2_CID_PRIVATE_COLORFILTER:
1462 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1463 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001464 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001465 return -EINVAL;
1466 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1467 qc->type = V4L2_CTRL_TYPE_MENU;
1468 qc->minimum = 0;
1469 qc->maximum = 1;
1470 qc->step = 1;
1471 qc->default_value = 1;
1472 qc->flags = 0;
1473 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001474 default:
1475 return -EINVAL;
1476 }
1477 dprintk(4, "%s, id %d\n", __func__, qc->id);
1478 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001479}
1480
1481static int vidioc_g_ctrl(struct file *file, void *priv,
1482 struct v4l2_control *ctrl)
1483{
Dean Anderson2e70db92010-03-05 14:29:09 -03001484 struct s2255_fh *fh = priv;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001485 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001486 struct s2255_channel *channel = fh->channel;
Dean Anderson2e70db92010-03-05 14:29:09 -03001487 switch (ctrl->id) {
1488 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001489 ctrl->value = channel->mode.bright;
Dean Anderson2e70db92010-03-05 14:29:09 -03001490 break;
1491 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001492 ctrl->value = channel->mode.contrast;
Dean Anderson2e70db92010-03-05 14:29:09 -03001493 break;
1494 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001495 ctrl->value = channel->mode.saturation;
Dean Anderson2e70db92010-03-05 14:29:09 -03001496 break;
1497 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001498 ctrl->value = channel->mode.hue;
Dean Anderson2e70db92010-03-05 14:29:09 -03001499 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001500 case V4L2_CID_PRIVATE_COLORFILTER:
1501 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1502 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001503 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001504 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001505 ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001506 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001507 default:
1508 return -EINVAL;
1509 }
1510 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1511 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001512}
1513
1514static int vidioc_s_ctrl(struct file *file, void *priv,
1515 struct v4l2_control *ctrl)
1516{
Dean Anderson38f993a2008-06-26 23:15:51 -03001517 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001518 struct s2255_channel *channel = fh->channel;
1519 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
1520 struct s2255_mode mode;
1521 mode = channel->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001522 dprintk(4, "%s\n", __func__);
1523 /* update the mode to the corresponding value */
1524 switch (ctrl->id) {
1525 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001526 mode.bright = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001527 break;
1528 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001529 mode.contrast = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001530 break;
1531 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001532 mode.hue = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001533 break;
1534 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001535 mode.saturation = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001536 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001537 case V4L2_CID_PRIVATE_COLORFILTER:
1538 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1539 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001540 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001541 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001542 mode.color &= ~MASK_INPUT_TYPE;
1543 mode.color |= ((ctrl->value ? 0 : 1) << 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001544 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001545 default:
1546 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001547 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001548 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001549 /* set mode here. Note: stream does not need restarted.
1550 some V4L programs restart stream unnecessarily
1551 after a s_crtl.
1552 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001553 s2255_set_mode(fh->channel, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001554 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001555}
1556
Dean Anderson22b88d42008-08-29 15:33:19 -03001557static int vidioc_g_jpegcomp(struct file *file, void *priv,
1558 struct v4l2_jpegcompression *jc)
1559{
1560 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001561 struct s2255_channel *channel = fh->channel;
1562 *jc = channel->jc;
Dean Anderson85b85482010-04-08 23:51:17 -03001563 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001564 return 0;
1565}
1566
1567static int vidioc_s_jpegcomp(struct file *file, void *priv,
1568 struct v4l2_jpegcompression *jc)
1569{
1570 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001571 struct s2255_channel *channel = fh->channel;
Dean Anderson22b88d42008-08-29 15:33:19 -03001572 if (jc->quality < 0 || jc->quality > 100)
1573 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001574 channel->jc.quality = jc->quality;
Dean Anderson85b85482010-04-08 23:51:17 -03001575 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001576 return 0;
1577}
Dean Anderson7d853532009-05-15 14:32:04 -03001578
1579static int vidioc_g_parm(struct file *file, void *priv,
1580 struct v4l2_streamparm *sp)
1581{
1582 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001583 __u32 def_num, def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001584 struct s2255_channel *channel = fh->channel;
Dean Anderson7d853532009-05-15 14:32:04 -03001585 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1586 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001587 memset(sp, 0, sizeof(struct v4l2_streamparm));
1588 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001589 sp->parm.capture.capturemode = channel->cap_parm.capturemode;
1590 def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1591 def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001592 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001593 switch (channel->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001594 default:
1595 case FDEC_1:
1596 sp->parm.capture.timeperframe.numerator = def_num;
1597 break;
1598 case FDEC_2:
1599 sp->parm.capture.timeperframe.numerator = def_num * 2;
1600 break;
1601 case FDEC_3:
1602 sp->parm.capture.timeperframe.numerator = def_num * 3;
1603 break;
1604 case FDEC_5:
1605 sp->parm.capture.timeperframe.numerator = def_num * 5;
1606 break;
1607 }
1608 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1609 sp->parm.capture.capturemode,
1610 sp->parm.capture.timeperframe.numerator,
1611 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001612 return 0;
1613}
1614
1615static int vidioc_s_parm(struct file *file, void *priv,
1616 struct v4l2_streamparm *sp)
1617{
1618 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001619 struct s2255_channel *channel = fh->channel;
1620 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001621 int fdec = FDEC_1;
1622 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001623 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1624 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001625 mode = channel->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001626 /* high quality capture mode requires a stream restart */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001627 if (channel->cap_parm.capturemode
1628 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001629 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001630 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1631 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001632 if (def_dem != sp->parm.capture.timeperframe.denominator)
1633 sp->parm.capture.timeperframe.numerator = def_num;
1634 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1635 sp->parm.capture.timeperframe.numerator = def_num;
1636 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1637 sp->parm.capture.timeperframe.numerator = def_num * 2;
1638 fdec = FDEC_2;
1639 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1640 sp->parm.capture.timeperframe.numerator = def_num * 3;
1641 fdec = FDEC_3;
1642 } else {
1643 sp->parm.capture.timeperframe.numerator = def_num * 5;
1644 fdec = FDEC_5;
1645 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001646 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001647 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001648 s2255_set_mode(channel, &mode);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001649 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1650 __func__,
1651 sp->parm.capture.capturemode,
1652 sp->parm.capture.timeperframe.numerator,
1653 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001654 return 0;
1655}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001656
1657static int vidioc_enum_frameintervals(struct file *file, void *priv,
1658 struct v4l2_frmivalenum *fe)
1659{
1660 int is_ntsc = 0;
1661#define NUM_FRAME_ENUMS 4
1662 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
1663 if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
1664 return -EINVAL;
1665 switch (fe->width) {
1666 case 640:
1667 if (fe->height != 240 && fe->height != 480)
1668 return -EINVAL;
1669 is_ntsc = 1;
1670 break;
1671 case 320:
1672 if (fe->height != 240)
1673 return -EINVAL;
1674 is_ntsc = 1;
1675 break;
1676 case 704:
1677 if (fe->height != 288 && fe->height != 576)
1678 return -EINVAL;
1679 break;
1680 case 352:
1681 if (fe->height != 288)
1682 return -EINVAL;
1683 break;
1684 default:
1685 return -EINVAL;
1686 }
1687 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1688 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1689 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1690 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1691 fe->discrete.denominator);
1692 return 0;
1693}
1694
Hans Verkuilbec43662008-12-30 06:58:20 -03001695static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001696{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001697 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001698 struct s2255_channel *channel = video_drvdata(file);
1699 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001700 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001701 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001702 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001703 dprintk(1, "s2255: open called (dev=%s)\n",
1704 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001705 /*
1706 * open lock necessary to prevent multiple instances
1707 * of v4l-conf (or other programs) from simultaneously
1708 * reloading firmware.
1709 */
Dean Anderson38f993a2008-06-26 23:15:51 -03001710 mutex_lock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001711 state = atomic_read(&dev->fw_data->fw_state);
1712 switch (state) {
1713 case S2255_FW_DISCONNECTING:
1714 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001715 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001716 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001717 s2255_dev_err(&dev->udev->dev,
1718 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001719 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001720 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001721 ((atomic_read(&dev->fw_data->fw_state)
1722 == S2255_FW_SUCCESS) ||
1723 (atomic_read(&dev->fw_data->fw_state)
1724 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001725 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001726 /* state may have changed, re-read */
1727 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001728 break;
1729 case S2255_FW_NOTLOADED:
1730 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001731 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1732 driver loaded and then device immediately opened */
1733 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1734 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001735 ((atomic_read(&dev->fw_data->fw_state)
1736 == S2255_FW_SUCCESS) ||
1737 (atomic_read(&dev->fw_data->fw_state)
1738 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001739 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001740 /* state may have changed, re-read */
1741 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001742 break;
1743 case S2255_FW_SUCCESS:
1744 default:
1745 break;
1746 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001747 /* state may have changed in above switch statement */
1748 switch (state) {
1749 case S2255_FW_SUCCESS:
1750 break;
1751 case S2255_FW_FAILED:
1752 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Andersoneb78dee2010-04-12 15:05:37 -03001753 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001754 return -ENODEV;
1755 case S2255_FW_DISCONNECTING:
1756 printk(KERN_INFO "%s: disconnecting\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001757 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001758 return -ENODEV;
1759 case S2255_FW_LOADED_DSPWAIT:
1760 case S2255_FW_NOTLOADED:
1761 printk(KERN_INFO "%s: firmware not loaded yet"
1762 "please try again later\n",
1763 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001764 /*
1765 * Timeout on firmware load means device unusable.
1766 * Set firmware failure state.
1767 * On next s2255_open the firmware will be reloaded.
1768 */
1769 atomic_set(&dev->fw_data->fw_state,
1770 S2255_FW_FAILED);
1771 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001772 return -EAGAIN;
1773 default:
1774 printk(KERN_INFO "%s: unknown state\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001775 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001776 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001777 }
Dean Andersoneb78dee2010-04-12 15:05:37 -03001778 mutex_unlock(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001779 /* allocate + initialize per filehandle data */
1780 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001781 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001782 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03001783 file->private_data = fh;
1784 fh->dev = dev;
1785 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001786 fh->channel = channel;
1787 if (!channel->configured) {
1788 /* configure channel to default state */
1789 channel->fmt = &formats[0];
1790 s2255_set_mode(channel, &channel->mode);
1791 channel->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001792 }
Dean Anderson85b85482010-04-08 23:51:17 -03001793 dprintk(1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001794 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson85b85482010-04-08 23:51:17 -03001795 dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001796 (unsigned long)fh, (unsigned long)dev,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001797 (unsigned long)&channel->vidq);
Dean Anderson85b85482010-04-08 23:51:17 -03001798 dprintk(4, "%s: list_empty active=%d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001799 list_empty(&channel->vidq.active));
Dean Anderson38f993a2008-06-26 23:15:51 -03001800 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1801 NULL, &dev->slock,
1802 fh->type,
1803 V4L2_FIELD_INTERLACED,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001804 sizeof(struct s2255_buffer),
1805 fh, vdev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001806 return 0;
1807}
1808
1809
1810static unsigned int s2255_poll(struct file *file,
1811 struct poll_table_struct *wait)
1812{
1813 struct s2255_fh *fh = file->private_data;
1814 int rc;
1815 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001816 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1817 return POLLERR;
Dean Anderson38f993a2008-06-26 23:15:51 -03001818 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
1819 return rc;
1820}
1821
Dean Andersond62e85a2010-04-09 19:54:26 -03001822static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001823{
Dean Anderson38f993a2008-06-26 23:15:51 -03001824 /* board shutdown stops the read pipe if it is running */
1825 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001826 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001827 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001828 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001829 usb_kill_urb(dev->fw_data->fw_urb);
1830 usb_free_urb(dev->fw_data->fw_urb);
1831 dev->fw_data->fw_urb = NULL;
1832 }
Dean Andersonf78d92c2008-07-22 14:43:27 -03001833 if (dev->fw_data->fw)
1834 release_firmware(dev->fw_data->fw);
1835 kfree(dev->fw_data->pfw_data);
1836 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001837 /* reset the DSP so firmware can be reloaded next time */
1838 s2255_reset_dsppower(dev);
1839 mutex_destroy(&dev->open_lock);
1840 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001841 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001842 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001843 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001844 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001845}
1846
Dean Andersonff7e22d2010-04-08 23:38:07 -03001847static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001848{
1849 struct s2255_fh *fh = file->private_data;
1850 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001851 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001852 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001853 if (!dev)
1854 return -ENODEV;
Dean Andersonf78d92c2008-07-22 14:43:27 -03001855 /* turn off stream */
1856 if (res_check(fh)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001857 if (channel->b_acquire)
1858 s2255_stop_acquire(fh->channel);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001859 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001860 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001861 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001862 videobuf_mmap_free(&fh->vb_vidq);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001863 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001864 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001865 return 0;
1866}
1867
1868static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1869{
1870 struct s2255_fh *fh = file->private_data;
1871 int ret;
1872
1873 if (!fh)
1874 return -ENODEV;
Dean Anderson85b85482010-04-08 23:51:17 -03001875 dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Dean Anderson38f993a2008-06-26 23:15:51 -03001876 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
Dean Anderson85b85482010-04-08 23:51:17 -03001877 dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001878 (unsigned long)vma->vm_start,
1879 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001880 return ret;
1881}
1882
Hans Verkuilbec43662008-12-30 06:58:20 -03001883static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001884 .owner = THIS_MODULE,
1885 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001886 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001887 .poll = s2255_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001888 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001889 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001890};
1891
Hans Verkuila3998102008-07-21 02:57:38 -03001892static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001893 .vidioc_querymenu = vidioc_querymenu,
Dean Anderson38f993a2008-06-26 23:15:51 -03001894 .vidioc_querycap = vidioc_querycap,
1895 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1896 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1897 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1898 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1899 .vidioc_reqbufs = vidioc_reqbufs,
1900 .vidioc_querybuf = vidioc_querybuf,
1901 .vidioc_qbuf = vidioc_qbuf,
1902 .vidioc_dqbuf = vidioc_dqbuf,
1903 .vidioc_s_std = vidioc_s_std,
1904 .vidioc_enum_input = vidioc_enum_input,
1905 .vidioc_g_input = vidioc_g_input,
1906 .vidioc_s_input = vidioc_s_input,
1907 .vidioc_queryctrl = vidioc_queryctrl,
1908 .vidioc_g_ctrl = vidioc_g_ctrl,
1909 .vidioc_s_ctrl = vidioc_s_ctrl,
1910 .vidioc_streamon = vidioc_streamon,
1911 .vidioc_streamoff = vidioc_streamoff,
1912#ifdef CONFIG_VIDEO_V4L1_COMPAT
1913 .vidiocgmbuf = vidioc_cgmbuf,
1914#endif
Dean Anderson22b88d42008-08-29 15:33:19 -03001915 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1916 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001917 .vidioc_s_parm = vidioc_s_parm,
1918 .vidioc_g_parm = vidioc_g_parm,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001919 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuila3998102008-07-21 02:57:38 -03001920};
1921
Dean Andersonff7e22d2010-04-08 23:38:07 -03001922static void s2255_video_device_release(struct video_device *vdev)
1923{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001924 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
1925 dprintk(4, "%s, chnls: %d \n", __func__,
1926 atomic_read(&dev->num_channels));
1927 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001928 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001929 return;
1930}
1931
Hans Verkuila3998102008-07-21 02:57:38 -03001932static struct video_device template = {
1933 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001934 .fops = &s2255_fops_v4l,
1935 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001936 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001937 .tvnorms = S2255_NORMS,
1938 .current_norm = V4L2_STD_NTSC_M,
1939};
1940
1941static int s2255_probe_v4l(struct s2255_dev *dev)
1942{
1943 int ret;
1944 int i;
1945 int cur_nr = video_nr;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001946 struct s2255_channel *channel;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001947 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1948 if (ret)
1949 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001950 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001951 /* register 4 video devices */
1952 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001953 channel = &dev->channel[i];
1954 INIT_LIST_HEAD(&channel->vidq.active);
1955 channel->vidq.dev = dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001956 /* register 4 video devices */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001957 channel->vdev = template;
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001958 channel->vdev.lock = &dev->lock;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001959 channel->vdev.v4l2_dev = &dev->v4l2_dev;
1960 video_set_drvdata(&channel->vdev, channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03001961 if (video_nr == -1)
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 video_nr);
1965 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001966 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001967 VFL_TYPE_GRABBER,
1968 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001969
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001970 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001971 dev_err(&dev->udev->dev,
1972 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001973 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001974 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001975 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001976 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001977 video_device_node_name(&channel->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001978
Dean Anderson38f993a2008-06-26 23:15:51 -03001979 }
Dean Andersonabce21f2009-04-23 16:04:41 -03001980 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
1981 S2255_MAJOR_VERSION,
1982 S2255_MINOR_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001983 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001984 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001985 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001986 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001987 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001988 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001989 printk(KERN_WARNING "s2255: Not all channels available.\n");
1990 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001991}
1992
Dean Anderson38f993a2008-06-26 23:15:51 -03001993/* this function moves the usb stream read pipe data
1994 * into the system buffers.
1995 * returns 0 on success, EAGAIN if more data to process( call this
1996 * function again).
1997 *
1998 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001999 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03002000 * bytes 4-7: channel: 0-3
2001 * bytes 8-11: payload size: size of the frame
2002 * bytes 12-payloadsize+12: frame data
2003 */
2004static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
2005{
Dean Anderson38f993a2008-06-26 23:15:51 -03002006 char *pdest;
2007 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002008 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002009 char *psrc;
2010 unsigned long copy_size;
2011 unsigned long size;
2012 s32 idx = -1;
2013 struct s2255_framei *frm;
2014 unsigned char *pdata;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002015 struct s2255_channel *channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03002016 dprintk(100, "buffer to user\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002017 channel = &dev->channel[dev->cc];
2018 idx = channel->cur_frame;
2019 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002020 if (frm->ulState == S2255_READ_IDLE) {
2021 int jj;
2022 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03002023 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03002024 int payload;
2025 /* search for marker codes */
2026 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03002027 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002028 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03002029 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03002030 case S2255_MARKER_FRAME:
Dean Anderson14d96262008-08-25 13:58:55 -03002031 dprintk(4, "found frame marker at offset:"
2032 " %d [%x %x]\n", jj, pdata[0],
2033 pdata[1]);
2034 offset = jj + PREFIX_SIZE;
2035 bframe = 1;
2036 cc = pdword[1];
2037 if (cc >= MAX_CHANNELS) {
2038 printk(KERN_ERR
2039 "bad channel\n");
2040 return -EINVAL;
2041 }
2042 /* reverse it */
2043 dev->cc = G_chnmap[cc];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002044 channel = &dev->channel[dev->cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002045 payload = pdword[3];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002046 if (payload > channel->req_image_size) {
2047 channel->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03002048 /* discard the bad frame */
2049 return -EINVAL;
2050 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002051 channel->pkt_size = payload;
2052 channel->jpg_size = pdword[4];
Dean Anderson14d96262008-08-25 13:58:55 -03002053 break;
2054 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002055
Dean Anderson14d96262008-08-25 13:58:55 -03002056 pdata += DEF_USB_BLOCK;
2057 jj += DEF_USB_BLOCK;
2058 if (pdword[1] >= MAX_CHANNELS)
2059 break;
2060 cc = G_chnmap[pdword[1]];
Roel Kluinf14a2972009-10-23 07:59:42 -03002061 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002062 break;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002063 channel = &dev->channel[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002064 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03002065 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03002066 /* check if channel valid */
2067 /* set mode ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002068 channel->setmode_ready = 1;
2069 wake_up(&channel->wait_setmode);
Dean Anderson14d96262008-08-25 13:58:55 -03002070 dprintk(5, "setmode ready %d\n", cc);
2071 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002072 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002073 dev->chn_ready |= (1 << cc);
2074 if ((dev->chn_ready & 0x0f) != 0x0f)
2075 break;
2076 /* all channels ready */
2077 printk(KERN_INFO "s2255: fw loaded\n");
2078 atomic_set(&dev->fw_data->fw_state,
2079 S2255_FW_SUCCESS);
2080 wake_up(&dev->fw_data->wait_fw);
2081 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002082 case S2255_RESPONSE_STATUS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002083 channel->vidstatus = pdword[3];
2084 channel->vidstatus_ready = 1;
2085 wake_up(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002086 dprintk(5, "got vidstatus %x chan %d\n",
2087 pdword[3], cc);
2088 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002089 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02002090 printk(KERN_INFO "s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002091 }
2092 default:
2093 pdata++;
2094 break;
2095 }
2096 if (bframe)
2097 break;
2098 } /* for */
2099 if (!bframe)
2100 return -EINVAL;
2101 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002102 channel = &dev->channel[dev->cc];
2103 idx = channel->cur_frame;
2104 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002105 /* search done. now find out if should be acquiring on this channel */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002106 if (!channel->b_acquire) {
Dean Anderson14d96262008-08-25 13:58:55 -03002107 /* we found a frame, but this channel is turned off */
2108 frm->ulState = S2255_READ_IDLE;
2109 return -EINVAL;
2110 }
2111
2112 if (frm->ulState == S2255_READ_IDLE) {
2113 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002114 frm->cur_size = 0;
2115 }
2116
Dean Anderson14d96262008-08-25 13:58:55 -03002117 /* skip the marker 512 bytes (and offset if out of sync) */
2118 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2119
Dean Anderson38f993a2008-06-26 23:15:51 -03002120
2121 if (frm->lpvbits == NULL) {
2122 dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
2123 frm, dev, dev->cc, idx);
2124 return -ENOMEM;
2125 }
2126
2127 pdest = frm->lpvbits + frm->cur_size;
2128
Dean Anderson14d96262008-08-25 13:58:55 -03002129 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002130
Dean Andersonfe85ce92010-06-01 19:12:07 -03002131 size = channel->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002132
Dean Anderson14d96262008-08-25 13:58:55 -03002133 /* sanity check on pdest */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002134 if ((copy_size + frm->cur_size) < channel->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03002135 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002136
Dean Anderson38f993a2008-06-26 23:15:51 -03002137 frm->cur_size += copy_size;
Dean Anderson14d96262008-08-25 13:58:55 -03002138 dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002139
Dean Anderson14d96262008-08-25 13:58:55 -03002140 if (frm->cur_size >= size) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002141 dprintk(2, "****************[%d]Buffer[%d]full*************\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002142 dev->cc, idx);
2143 channel->last_frame = channel->cur_frame;
2144 channel->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002145 /* end of system frame ring buffer, start at zero */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002146 if ((channel->cur_frame == SYS_FRAMES) ||
2147 (channel->cur_frame == channel->buffer.dwFrames))
2148 channel->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002149 /* frame ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002150 if (channel->b_acquire)
2151 s2255_got_frame(channel, channel->jpg_size);
2152 channel->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03002153 frm->ulState = S2255_READ_IDLE;
2154 frm->cur_size = 0;
2155
Dean Anderson38f993a2008-06-26 23:15:51 -03002156 }
2157 /* done successfully */
2158 return 0;
2159}
2160
2161static void s2255_read_video_callback(struct s2255_dev *dev,
2162 struct s2255_pipeinfo *pipe_info)
2163{
2164 int res;
2165 dprintk(50, "callback read video \n");
2166
2167 if (dev->cc >= MAX_CHANNELS) {
2168 dev->cc = 0;
2169 dev_err(&dev->udev->dev, "invalid channel\n");
2170 return;
2171 }
2172 /* otherwise copy to the system buffers */
2173 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002174 if (res != 0)
2175 dprintk(4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002176
2177 dprintk(50, "callback read video done\n");
2178 return;
2179}
2180
2181static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2182 u16 Index, u16 Value, void *TransferBuffer,
2183 s32 TransferBufferLength, int bOut)
2184{
2185 int r;
2186 if (!bOut) {
2187 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2188 Request,
2189 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2190 USB_DIR_IN,
2191 Value, Index, TransferBuffer,
2192 TransferBufferLength, HZ * 5);
2193 } else {
2194 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2195 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2196 Value, Index, TransferBuffer,
2197 TransferBufferLength, HZ * 5);
2198 }
2199 return r;
2200}
2201
2202/*
2203 * retrieve FX2 firmware version. future use.
2204 * @param dev pointer to device extension
2205 * @return -1 for fail, else returns firmware version as an int(16 bits)
2206 */
2207static int s2255_get_fx2fw(struct s2255_dev *dev)
2208{
2209 int fw;
2210 int ret;
2211 unsigned char transBuffer[64];
2212 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2213 S2255_VR_IN);
2214 if (ret < 0)
2215 dprintk(2, "get fw error: %x\n", ret);
2216 fw = transBuffer[0] + (transBuffer[1] << 8);
2217 dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
2218 return fw;
2219}
2220
2221/*
2222 * Create the system ring buffer to copy frames into from the
2223 * usb read pipe.
2224 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002225static int s2255_create_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002226{
2227 unsigned long i;
2228 unsigned long reqsize;
2229 dprintk(1, "create sys buffers\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002230 channel->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03002231 /* always allocate maximum size(PAL) for system buffers */
2232 reqsize = SYS_FRAMES_MAXSIZE;
2233
2234 if (reqsize > SYS_FRAMES_MAXSIZE)
2235 reqsize = SYS_FRAMES_MAXSIZE;
2236
2237 for (i = 0; i < SYS_FRAMES; i++) {
2238 /* allocate the frames */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002239 channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
2240 dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
2241 &channel->buffer.frame[i], channel->idx, i,
2242 channel->buffer.frame[i].lpvbits);
2243 channel->buffer.frame[i].size = reqsize;
2244 if (channel->buffer.frame[i].lpvbits == NULL) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002245 printk(KERN_INFO "out of memory. using less frames\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002246 channel->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002247 break;
2248 }
2249 }
2250
2251 /* make sure internal states are set */
2252 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002253 channel->buffer.frame[i].ulState = 0;
2254 channel->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002255 }
2256
Dean Andersonfe85ce92010-06-01 19:12:07 -03002257 channel->cur_frame = 0;
2258 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002259 return 0;
2260}
2261
Dean Andersonfe85ce92010-06-01 19:12:07 -03002262static int s2255_release_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002263{
2264 unsigned long i;
2265 dprintk(1, "release sys buffers\n");
2266 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002267 if (channel->buffer.frame[i].lpvbits) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002268 dprintk(1, "vfree %p\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002269 channel->buffer.frame[i].lpvbits);
2270 vfree(channel->buffer.frame[i].lpvbits);
Dean Anderson38f993a2008-06-26 23:15:51 -03002271 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002272 channel->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002273 }
2274 return 0;
2275}
2276
2277static int s2255_board_init(struct s2255_dev *dev)
2278{
Dean Anderson38f993a2008-06-26 23:15:51 -03002279 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2280 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002281 int j;
2282 struct s2255_pipeinfo *pipe = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002283 dprintk(4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002284 memset(pipe, 0, sizeof(*pipe));
2285 pipe->dev = dev;
2286 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2287 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002288
Dean Andersonab85c6a2010-04-08 23:39:12 -03002289 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2290 GFP_KERNEL);
2291 if (pipe->transfer_buffer == NULL) {
2292 dprintk(1, "out of memory!\n");
2293 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002294 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002295 /* query the firmware */
2296 fw_ver = s2255_get_fx2fw(dev);
2297
Dean Andersonabce21f2009-04-23 16:04:41 -03002298 printk(KERN_INFO "2255 usb firmware version %d.%d\n",
2299 (fw_ver >> 8) & 0xff,
2300 fw_ver & 0xff);
2301
2302 if (fw_ver < S2255_CUR_USB_FWVER)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002303 dev_err(&dev->udev->dev,
Dean Andersonabce21f2009-04-23 16:04:41 -03002304 "usb firmware not up to date %d.%d\n",
2305 (fw_ver >> 8) & 0xff,
2306 fw_ver & 0xff);
Dean Anderson38f993a2008-06-26 23:15:51 -03002307
2308 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002309 struct s2255_channel *channel = &dev->channel[j];
2310 channel->b_acquire = 0;
2311 channel->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002312 if (dev->pid == 0x2257 && j > 1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002313 channel->mode.color |= (1 << 16);
2314 channel->jc.quality = S2255_DEF_JPEG_QUAL;
2315 channel->width = LINE_SZ_4CIFS_NTSC;
2316 channel->height = NUM_LINES_4CIFS_NTSC * 2;
2317 channel->fmt = &formats[0];
2318 channel->mode.restart = 1;
2319 channel->req_image_size = get_transfer_size(&mode_def);
2320 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002321 /* create the system buffers */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002322 s2255_create_sys_buffers(channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03002323 }
2324 /* start read pipe */
2325 s2255_start_readpipe(dev);
Dean Anderson85b85482010-04-08 23:51:17 -03002326 dprintk(1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002327 return 0;
2328}
2329
2330static int s2255_board_shutdown(struct s2255_dev *dev)
2331{
2332 u32 i;
Dean Anderson85b85482010-04-08 23:51:17 -03002333 dprintk(1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002334
2335 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002336 if (dev->channel[i].b_acquire)
2337 s2255_stop_acquire(&dev->channel[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002338 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002339 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002340 for (i = 0; i < MAX_CHANNELS; i++)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002341 s2255_release_sys_buffers(&dev->channel[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002342 /* release transfer buffer */
2343 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002344 return 0;
2345}
2346
2347static void read_pipe_completion(struct urb *purb)
2348{
2349 struct s2255_pipeinfo *pipe_info;
2350 struct s2255_dev *dev;
2351 int status;
2352 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002353 pipe_info = purb->context;
Dean Anderson85b85482010-04-08 23:51:17 -03002354 dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
Dean Anderson38f993a2008-06-26 23:15:51 -03002355 purb->status);
2356 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002357 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002358 return;
2359 }
2360
2361 dev = pipe_info->dev;
2362 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002363 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002364 return;
2365 }
2366 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002367 /* if shutting down, do not resubmit, exit immediately */
2368 if (status == -ESHUTDOWN) {
Dean Anderson85b85482010-04-08 23:51:17 -03002369 dprintk(2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002370 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002371 return;
2372 }
2373
2374 if (pipe_info->state == 0) {
Dean Anderson85b85482010-04-08 23:51:17 -03002375 dprintk(2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002376 return;
2377 }
2378
Dean Andersonb02064c2009-04-30 12:29:38 -03002379 if (status == 0)
2380 s2255_read_video_callback(dev, pipe_info);
2381 else {
2382 pipe_info->err_count++;
Dean Anderson85b85482010-04-08 23:51:17 -03002383 dprintk(1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002384 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002385
Dean Anderson38f993a2008-06-26 23:15:51 -03002386 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2387 /* reuse urb */
2388 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2389 pipe,
2390 pipe_info->transfer_buffer,
2391 pipe_info->cur_transfer_size,
2392 read_pipe_completion, pipe_info);
2393
2394 if (pipe_info->state != 0) {
2395 if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) {
2396 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002397 }
2398 } else {
Dean Anderson85b85482010-04-08 23:51:17 -03002399 dprintk(2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002400 }
2401 return;
2402}
2403
2404static int s2255_start_readpipe(struct s2255_dev *dev)
2405{
2406 int pipe;
2407 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002408 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002409 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
Dean Anderson85b85482010-04-08 23:51:17 -03002410 dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002411 pipe_info->state = 1;
2412 pipe_info->err_count = 0;
2413 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2414 if (!pipe_info->stream_urb) {
2415 dev_err(&dev->udev->dev,
2416 "ReadStream: Unable to alloc URB\n");
2417 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002418 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002419 /* transfer buffer allocated in board_init */
2420 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2421 pipe,
2422 pipe_info->transfer_buffer,
2423 pipe_info->cur_transfer_size,
2424 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002425 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2426 if (retval) {
2427 printk(KERN_ERR "s2255: start read pipe failed\n");
2428 return retval;
2429 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002430 return 0;
2431}
2432
2433/* starts acquisition process */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002434static int s2255_start_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002435{
2436 unsigned char *buffer;
2437 int res;
2438 unsigned long chn_rev;
2439 int j;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002440 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2441 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002442 buffer = kzalloc(512, GFP_KERNEL);
2443 if (buffer == NULL) {
2444 dev_err(&dev->udev->dev, "out of mem\n");
2445 return -ENOMEM;
2446 }
2447
Dean Andersonfe85ce92010-06-01 19:12:07 -03002448 channel->last_frame = -1;
2449 channel->bad_payload = 0;
2450 channel->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002451 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002452 channel->buffer.frame[j].ulState = 0;
2453 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002454 }
2455
2456 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002457 *(__le32 *) buffer = IN_DATA_TOKEN;
2458 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2459 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002460 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2461 if (res != 0)
2462 dev_err(&dev->udev->dev, "CMD_START error\n");
2463
Dean Andersonfe85ce92010-06-01 19:12:07 -03002464 dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03002465 kfree(buffer);
2466 return 0;
2467}
2468
Dean Andersonfe85ce92010-06-01 19:12:07 -03002469static int s2255_stop_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002470{
2471 unsigned char *buffer;
2472 int res;
2473 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002474 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2475 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002476 buffer = kzalloc(512, GFP_KERNEL);
2477 if (buffer == NULL) {
2478 dev_err(&dev->udev->dev, "out of mem\n");
2479 return -ENOMEM;
2480 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002481 /* send the stop command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002482 *(__le32 *) buffer = IN_DATA_TOKEN;
2483 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2484 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002485 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002486 if (res != 0)
2487 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002488 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002489 channel->b_acquire = 0;
2490 dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
Dean Anderson14d96262008-08-25 13:58:55 -03002491 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002492}
2493
2494static void s2255_stop_readpipe(struct s2255_dev *dev)
2495{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002496 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002497
Dean Andersonab85c6a2010-04-08 23:39:12 -03002498 pipe->state = 0;
2499 if (pipe->stream_urb) {
2500 /* cancel urb */
2501 usb_kill_urb(pipe->stream_urb);
2502 usb_free_urb(pipe->stream_urb);
2503 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002504 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002505 dprintk(4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002506 return;
2507}
2508
Dean Anderson14d96262008-08-25 13:58:55 -03002509static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002510{
Dean Anderson14d96262008-08-25 13:58:55 -03002511 if (reset)
2512 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002513 dev->fw_data->fw_size = dev->fw_data->fw->size;
2514 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2515 memcpy(dev->fw_data->pfw_data,
2516 dev->fw_data->fw->data, CHUNK_SIZE);
2517 dev->fw_data->fw_loaded = CHUNK_SIZE;
2518 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2519 usb_sndbulkpipe(dev->udev, 2),
2520 dev->fw_data->pfw_data,
2521 CHUNK_SIZE, s2255_fwchunk_complete,
2522 dev->fw_data);
2523 mod_timer(&dev->timer, jiffies + HZ);
2524}
2525
2526/* standard usb probe function */
2527static int s2255_probe(struct usb_interface *interface,
2528 const struct usb_device_id *id)
2529{
2530 struct s2255_dev *dev = NULL;
2531 struct usb_host_interface *iface_desc;
2532 struct usb_endpoint_descriptor *endpoint;
2533 int i;
2534 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002535 __le32 *pdata;
2536 int fw_size;
Dean Anderson85b85482010-04-08 23:51:17 -03002537 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002538 /* allocate memory for our device state and initialize it to zero */
2539 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2540 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002541 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002542 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002543 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002544 atomic_set(&dev->num_channels, 0);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002545 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002546 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2547 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002548 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002549 mutex_init(&dev->lock);
2550 mutex_init(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002551 /* grab usb_device and save it */
2552 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2553 if (dev->udev == NULL) {
2554 dev_err(&interface->dev, "null usb device\n");
2555 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002556 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002557 }
Dean Andersond62e85a2010-04-09 19:54:26 -03002558 dprintk(1, "dev: %p, udev %p interface %p\n", dev,
Dean Anderson38f993a2008-06-26 23:15:51 -03002559 dev->udev, interface);
2560 dev->interface = interface;
2561 /* set up the endpoint information */
2562 iface_desc = interface->cur_altsetting;
2563 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2564 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2565 endpoint = &iface_desc->endpoint[i].desc;
2566 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2567 /* we found the bulk in endpoint */
2568 dev->read_endpoint = endpoint->bEndpointAddress;
2569 }
2570 }
2571
2572 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002573 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002574 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002575 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002576 init_timer(&dev->timer);
2577 dev->timer.function = s2255_timer;
2578 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002579 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002580 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002581 struct s2255_channel *channel = &dev->channel[i];
2582 dev->channel[i].idx = i;
2583 init_waitqueue_head(&channel->wait_setmode);
2584 init_waitqueue_head(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002585 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002586
2587 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002588 if (!dev->fw_data->fw_urb) {
2589 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002590 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002591 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002592
Dean Anderson38f993a2008-06-26 23:15:51 -03002593 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2594 if (!dev->fw_data->pfw_data) {
2595 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002596 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002597 }
2598 /* load the first chunk */
2599 if (request_firmware(&dev->fw_data->fw,
2600 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2601 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002602 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002603 }
Dean Anderson14d96262008-08-25 13:58:55 -03002604 /* check the firmware is valid */
2605 fw_size = dev->fw_data->fw->size;
2606 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002607
Dean Anderson14d96262008-08-25 13:58:55 -03002608 if (*pdata != S2255_FW_MARKER) {
2609 printk(KERN_INFO "Firmware invalid.\n");
2610 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002611 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002612 } else {
2613 /* make sure firmware is the latest */
2614 __le32 *pRel;
2615 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2616 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dean Anderson4de39f52010-03-03 19:39:19 -03002617 dev->dsp_fw_ver = *pRel;
2618 if (*pRel < S2255_CUR_DSP_FWVER)
2619 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002620 if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002621 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
Dean Andersonfe85ce92010-06-01 19:12:07 -03002622 " or above.\n", S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002623 }
Dean Anderson14d96262008-08-25 13:58:55 -03002624 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002625 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002626 retval = s2255_board_init(dev);
2627 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002628 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002629 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002630 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002631 /* loads v4l specific */
2632 retval = s2255_probe_v4l(dev);
2633 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002634 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002635 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2636 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002637errorBOARDINIT:
2638 s2255_board_shutdown(dev);
2639errorFWMARKER:
2640 release_firmware(dev->fw_data->fw);
2641errorREQFW:
2642 kfree(dev->fw_data->pfw_data);
2643errorFWDATA2:
2644 usb_free_urb(dev->fw_data->fw_urb);
2645errorFWURB:
2646 del_timer(&dev->timer);
2647errorEP:
2648 usb_put_dev(dev->udev);
2649errorUDEV:
2650 kfree(dev->fw_data);
2651 mutex_destroy(&dev->open_lock);
2652 mutex_destroy(&dev->lock);
2653errorFWDATA1:
2654 kfree(dev);
2655 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002656 return retval;
2657}
2658
2659/* disconnect routine. when board is removed physically or with rmmod */
2660static void s2255_disconnect(struct usb_interface *interface)
2661{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002662 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002663 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002664 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002665 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002666 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002667 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002668 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002669 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002670 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002671 for (i = 0; i < channels; i++)
2672 video_unregister_device(&dev->channel[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002673 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002674 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2675 wake_up(&dev->fw_data->wait_fw);
2676 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002677 dev->channel[i].setmode_ready = 1;
2678 wake_up(&dev->channel[i].wait_setmode);
2679 dev->channel[i].vidstatus_ready = 1;
2680 wake_up(&dev->channel[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002681 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002682 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002683 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002684 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002685}
2686
2687static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002688 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002689 .probe = s2255_probe,
2690 .disconnect = s2255_disconnect,
2691 .id_table = s2255_table,
2692};
2693
2694static int __init usb_s2255_init(void)
2695{
2696 int result;
Dean Anderson38f993a2008-06-26 23:15:51 -03002697 /* register this driver with the USB subsystem */
2698 result = usb_register(&s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002699 if (result)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002700 pr_err(KBUILD_MODNAME
Dean Andersonff7e22d2010-04-08 23:38:07 -03002701 ": usb_register failed. Error number %d\n", result);
2702 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002703 return result;
2704}
2705
2706static void __exit usb_s2255_exit(void)
2707{
2708 usb_deregister(&s2255_driver);
2709}
2710
2711module_init(usb_s2255_init);
2712module_exit(usb_s2255_exit);
2713
2714MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2715MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2716MODULE_LICENSE("GPL");