blob: 704e2cb1e459e644761db64eb9efcb4421f67541 [file] [log] [blame]
Dean Anderson38f993a2008-06-26 23:15:51 -03001/*
2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
3 *
Dean Anderson4de39f52010-03-03 19:39:19 -03004 * Copyright (C) 2007-2010 by Sensoray Company Inc.
Dean Anderson38f993a2008-06-26 23:15:51 -03005 * Dean Anderson
6 *
7 * Some video buffer code based on vivi driver:
8 *
9 * Sensoray 2255 device supports 4 simultaneous channels.
10 * The channels are not "crossbar" inputs, they are physically
11 * attached to separate video decoders.
12 *
13 * Because of USB2.0 bandwidth limitations. There is only a
14 * certain amount of data which may be transferred at one time.
15 *
16 * Example maximum bandwidth utilization:
17 *
18 * -full size, color mode YUYV or YUV422P: 2 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030019 * -full or half size Grey scale: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030020 * -half size, color mode YUYV or YUV422P: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030021 * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
22 * at once.
Dean Anderson38f993a2008-06-26 23:15:51 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * (at your option) any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 */
38
39#include <linux/module.h>
40#include <linux/firmware.h>
41#include <linux/kernel.h>
42#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090043#include <linux/slab.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030044#include <linux/videodev2.h>
45#include <linux/version.h>
Hans Verkuilfeb75f02008-07-27 06:30:21 -030046#include <linux/mm.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030047#include <media/videobuf-vmalloc.h>
48#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030049#include <media/v4l2-device.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030050#include <media/v4l2-ioctl.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030051#include <linux/vmalloc.h>
52#include <linux/usb.h>
53
Dean Anderson85b85482010-04-08 23:51:17 -030054#define S2255_MAJOR_VERSION 1
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -030055#define S2255_MINOR_VERSION 22
Dean Anderson85b85482010-04-08 23:51:17 -030056#define S2255_RELEASE 0
57#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
58 S2255_MINOR_VERSION, \
59 S2255_RELEASE)
Dean Anderson38f993a2008-06-26 23:15:51 -030060#define FIRMWARE_FILE_NAME "f2255usb.bin"
61
Dean Anderson22b88d42008-08-29 15:33:19 -030062/* default JPEG quality */
63#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030064/* vendor request in */
65#define S2255_VR_IN 0
66/* vendor request out */
67#define S2255_VR_OUT 1
68/* firmware query */
69#define S2255_VR_FW 0x30
70/* USB endpoint number for configuring the device */
71#define S2255_CONFIG_EP 2
72/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030073#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030074/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030075#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson38f993a2008-06-26 23:15:51 -030076#define S2255_DEF_BUFS 16
Dean Anderson14d96262008-08-25 13:58:55 -030077#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030078#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030079#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
80#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
81#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
82#define S2255_RESPONSE_FW cpu_to_le32(0x10)
83#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030084#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030085#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030086#define SYS_FRAMES 4
87/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030088#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
89#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030090#define LINE_SZ_4CIFS_NTSC 640
91#define LINE_SZ_2CIFS_NTSC 640
92#define LINE_SZ_1CIFS_NTSC 320
93#define LINE_SZ_4CIFS_PAL 704
94#define LINE_SZ_2CIFS_PAL 704
95#define LINE_SZ_1CIFS_PAL 352
96#define NUM_LINES_4CIFS_NTSC 240
97#define NUM_LINES_2CIFS_NTSC 240
98#define NUM_LINES_1CIFS_NTSC 240
99#define NUM_LINES_4CIFS_PAL 288
100#define NUM_LINES_2CIFS_PAL 288
101#define NUM_LINES_1CIFS_PAL 288
102#define LINE_SZ_DEF 640
103#define NUM_LINES_DEF 240
104
105
106/* predefined settings */
107#define FORMAT_NTSC 1
108#define FORMAT_PAL 2
109
110#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
111#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
112#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300113/* SCALE_4CIFSI is the 2 fields interpolated into one */
114#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300115
116#define COLOR_YUVPL 1 /* YUV planar */
117#define COLOR_YUVPK 2 /* YUV packed */
118#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300119#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300120
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300121#define MASK_COLOR 0x000000ff
122#define MASK_JPG_QUALITY 0x0000ff00
123#define MASK_INPUT_TYPE 0x000f0000
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300124/* frame decimation. */
Dean Anderson38f993a2008-06-26 23:15:51 -0300125#define FDEC_1 1 /* capture every frame. default */
126#define FDEC_2 2 /* capture every 2nd frame */
127#define FDEC_3 3 /* capture every 3rd frame */
128#define FDEC_5 5 /* capture every 5th frame */
129
130/*-------------------------------------------------------
131 * Default mode parameters.
132 *-------------------------------------------------------*/
133#define DEF_SCALE SCALE_4CIFS
134#define DEF_COLOR COLOR_YUVPL
135#define DEF_FDEC FDEC_1
136#define DEF_BRIGHT 0
137#define DEF_CONTRAST 0x5c
138#define DEF_SATURATION 0x80
139#define DEF_HUE 0
140
141/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300142#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
143#define CMD_2255 cpu_to_le32(0xc2255000)
144#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
145#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
146#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
147#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300148
149struct s2255_mode {
150 u32 format; /* input video format (NTSC, PAL) */
151 u32 scale; /* output video scale */
152 u32 color; /* output video color format */
153 u32 fdec; /* frame decimation */
154 u32 bright; /* brightness */
155 u32 contrast; /* contrast */
156 u32 saturation; /* saturation */
157 u32 hue; /* hue (NTSC only)*/
158 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
159 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
160 u32 restart; /* if DSP requires restart */
161};
162
Dean Anderson14d96262008-08-25 13:58:55 -0300163
164#define S2255_READ_IDLE 0
165#define S2255_READ_FRAME 1
166
Dean Anderson38f993a2008-06-26 23:15:51 -0300167/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300168struct s2255_framei {
169 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300170 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300171 void *lpvbits; /* image data */
172 unsigned long cur_size; /* current data copied to it */
173};
174
175/* image buffer structure */
176struct s2255_bufferi {
177 unsigned long dwFrames; /* number of frames in buffer */
178 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
179};
180
181#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
182 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300183 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300184
185struct s2255_dmaqueue {
186 struct list_head active;
Dean Anderson38f993a2008-06-26 23:15:51 -0300187 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300188};
189
190/* for firmware loading, fw_state */
191#define S2255_FW_NOTLOADED 0
192#define S2255_FW_LOADED_DSPWAIT 1
193#define S2255_FW_SUCCESS 2
194#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300195#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300196#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300197/* 2255 read states */
198#define S2255_READ_IDLE 0
199#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300200struct s2255_fw {
201 int fw_loaded;
202 int fw_size;
203 struct urb *fw_urb;
204 atomic_t fw_state;
205 void *pfw_data;
206 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300207 const struct firmware *fw;
208};
209
210struct s2255_pipeinfo {
211 u32 max_transfer_size;
212 u32 cur_transfer_size;
213 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300214 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300215 void *stream_urb;
216 void *dev; /* back pointer to s2255_dev struct*/
217 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300218 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300219};
220
221struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300222struct s2255_dev;
223
224struct s2255_channel {
225 struct video_device vdev;
226 int resources;
227 struct s2255_dmaqueue vidq;
228 struct s2255_bufferi buffer;
229 struct s2255_mode mode;
230 /* jpeg compression */
231 struct v4l2_jpegcompression jc;
232 /* capture parameters (for high quality mode full size) */
233 struct v4l2_captureparm cap_parm;
234 int cur_frame;
235 int last_frame;
236
237 int b_acquire;
238 /* allocated image size */
239 unsigned long req_image_size;
240 /* received packet size */
241 unsigned long pkt_size;
242 int bad_payload;
243 unsigned long frame_count;
244 /* if JPEG image */
245 int jpg_size;
246 /* if channel configured to default state */
247 int configured;
248 wait_queue_head_t wait_setmode;
249 int setmode_ready;
250 /* video status items */
251 int vidstatus;
252 wait_queue_head_t wait_vidstatus;
253 int vidstatus_ready;
254 unsigned int width;
255 unsigned int height;
256 const struct s2255_fmt *fmt;
257 int idx; /* channel number on device, 0-3 */
258};
259
Dean Anderson38f993a2008-06-26 23:15:51 -0300260
261struct s2255_dev {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300262 struct s2255_channel channel[MAX_CHANNELS];
Dean Anderson65c6edb2010-04-20 17:21:32 -0300263 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300264 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300265 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300266 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson38f993a2008-06-26 23:15:51 -0300267 struct mutex open_lock;
Dean Anderson38f993a2008-06-26 23:15:51 -0300268 struct usb_device *udev;
269 struct usb_interface *interface;
270 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300271 struct timer_list timer;
272 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300273 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300274 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300275 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300276 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300277 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300278 /* dsp firmware version (f2255usb.bin) */
279 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300280 u16 pid; /* product id */
Dean Anderson38f993a2008-06-26 23:15:51 -0300281};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300282
Dean Anderson65c6edb2010-04-20 17:21:32 -0300283static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
284{
285 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
286}
Dean Anderson38f993a2008-06-26 23:15:51 -0300287
288struct s2255_fmt {
289 char *name;
290 u32 fourcc;
291 int depth;
292};
293
294/* buffer for one video frame */
295struct s2255_buffer {
296 /* common v4l buffer stuff -- must be first */
297 struct videobuf_buffer vb;
298 const struct s2255_fmt *fmt;
299};
300
301struct s2255_fh {
302 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300303 struct videobuf_queue vb_vidq;
304 enum v4l2_buf_type type;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300305 struct s2255_channel *channel;
306 int resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300307};
308
Dean Andersonabce21f2009-04-23 16:04:41 -0300309/* current cypress EEPROM firmware version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300310#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
Dean Anderson4de39f52010-03-03 19:39:19 -0300311/* current DSP FW version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300312#define S2255_CUR_DSP_FWVER 10104
Dean Anderson4de39f52010-03-03 19:39:19 -0300313/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300314#define S2255_MIN_DSP_STATUS 5
315#define S2255_MIN_DSP_COLORFILTER 8
Dean Anderson38f993a2008-06-26 23:15:51 -0300316#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300317
318/* private V4L2 controls */
319
320/*
321 * The following chart displays how COLORFILTER should be set
322 * =========================================================
323 * = fourcc = COLORFILTER =
324 * = ===============================
325 * = = 0 = 1 =
326 * =========================================================
327 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
328 * = = s-video or = composite =
329 * = = B/W camera = input =
330 * =========================================================
331 * = other = color, svideo = color, =
332 * = = = composite =
333 * =========================================================
334 *
335 * Notes:
336 * channels 0-3 on 2255 are composite
337 * channels 0-1 on 2257 are composite, 2-3 are s-video
338 * If COLORFILTER is 0 with a composite color camera connected,
339 * the output will appear monochrome but hatching
340 * will occur.
341 * COLORFILTER is different from "color killer" and "color effects"
342 * for reasons above.
343 */
344#define S2255_V4L2_YC_ON 1
345#define S2255_V4L2_YC_OFF 0
346#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
347
Dean Anderson38f993a2008-06-26 23:15:51 -0300348/* frame prefix size (sent once every frame) */
349#define PREFIX_SIZE 512
350
351/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300352static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300353
Dean Anderson38f993a2008-06-26 23:15:51 -0300354static int debug;
355static int *s2255_debug = &debug;
356
357static int s2255_start_readpipe(struct s2255_dev *dev);
358static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300359static int s2255_start_acquire(struct s2255_channel *channel);
360static int s2255_stop_acquire(struct s2255_channel *channel);
361static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
362 int jpgsize);
363static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300364static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300365static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300366static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300367static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
368 u16 index, u16 value, void *buf,
369 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300370
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300371/* dev_err macro with driver name */
372#define S2255_DRIVER_NAME "s2255"
373#define s2255_dev_err(dev, fmt, arg...) \
374 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
375
Dean Anderson38f993a2008-06-26 23:15:51 -0300376#define dprintk(level, fmt, arg...) \
377 do { \
378 if (*s2255_debug >= (level)) { \
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300379 printk(KERN_DEBUG S2255_DRIVER_NAME \
380 ": " fmt, ##arg); \
Dean Anderson38f993a2008-06-26 23:15:51 -0300381 } \
382 } while (0)
383
Dean Anderson38f993a2008-06-26 23:15:51 -0300384static struct usb_driver s2255_driver;
385
Dean Anderson38f993a2008-06-26 23:15:51 -0300386/* Declare static vars that will be used as parameters */
387static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
388
389/* start video number */
390static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
391
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300392/* Enable jpeg capture. */
393static int jpeg_enable = 1;
394
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300395module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300396MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300397module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300398MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300399module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300400MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300401module_param(jpeg_enable, int, 0644);
402MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
Dean Anderson38f993a2008-06-26 23:15:51 -0300403
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. */
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300416/* JPEG formats must be defined last to support jpeg_enable parameter */
Dean Anderson38f993a2008-06-26 23:15:51 -0300417static const struct s2255_fmt formats[] = {
418 {
419 .name = "4:2:2, planar, YUV422P",
420 .fourcc = V4L2_PIX_FMT_YUV422P,
421 .depth = 16
422
423 }, {
424 .name = "4:2:2, packed, YUYV",
425 .fourcc = V4L2_PIX_FMT_YUYV,
426 .depth = 16
427
428 }, {
429 .name = "4:2:2, packed, UYVY",
430 .fourcc = V4L2_PIX_FMT_UYVY,
431 .depth = 16
432 }, {
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300433 .name = "8bpp GREY",
434 .fourcc = V4L2_PIX_FMT_GREY,
435 .depth = 8
436 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300437 .name = "JPG",
438 .fourcc = V4L2_PIX_FMT_JPEG,
439 .depth = 24
440 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300441 .name = "MJPG",
442 .fourcc = V4L2_PIX_FMT_MJPEG,
443 .depth = 24
Dean Anderson38f993a2008-06-26 23:15:51 -0300444 }
445};
446
447static int norm_maxw(struct video_device *vdev)
448{
449 return (vdev->current_norm & V4L2_STD_NTSC) ?
450 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
451}
452
453static int norm_maxh(struct video_device *vdev)
454{
455 return (vdev->current_norm & V4L2_STD_NTSC) ?
456 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
457}
458
459static int norm_minw(struct video_device *vdev)
460{
461 return (vdev->current_norm & V4L2_STD_NTSC) ?
462 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
463}
464
465static int norm_minh(struct video_device *vdev)
466{
467 return (vdev->current_norm & V4L2_STD_NTSC) ?
468 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
469}
470
471
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300472/*
473 * TODO: fixme: move YUV reordering to hardware
474 * converts 2255 planar format to yuyv or uyvy
475 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300476static void planar422p_to_yuv_packed(const unsigned char *in,
477 unsigned char *out,
478 int width, int height,
479 int fmt)
480{
481 unsigned char *pY;
482 unsigned char *pCb;
483 unsigned char *pCr;
484 unsigned long size = height * width;
485 unsigned int i;
486 pY = (unsigned char *)in;
487 pCr = (unsigned char *)in + height * width;
488 pCb = (unsigned char *)in + height * width + (height * width / 2);
489 for (i = 0; i < size * 2; i += 4) {
490 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
491 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
492 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
493 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
494 }
495 return;
496}
497
Hans Verkuild45b9b82008-09-04 03:33:43 -0300498static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300499{
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300500 s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300501 msleep(10);
502 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300503 msleep(600);
504 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300505 return;
506}
Dean Anderson38f993a2008-06-26 23:15:51 -0300507
508/* kickstarts the firmware loading. from probe
509 */
510static void s2255_timer(unsigned long user_data)
511{
512 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson85b85482010-04-08 23:51:17 -0300513 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300514 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
515 printk(KERN_ERR "s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300516 atomic_set(&data->fw_state, S2255_FW_FAILED);
517 /* wake up anything waiting for the firmware */
518 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300519 return;
520 }
521}
522
Dean Anderson38f993a2008-06-26 23:15:51 -0300523
524/* this loads the firmware asynchronously.
525 Originally this was done synchroously in probe.
526 But it is better to load it asynchronously here than block
527 inside the probe function. Blocking inside probe affects boot time.
528 FW loading is triggered by the timer in the probe function
529*/
530static void s2255_fwchunk_complete(struct urb *urb)
531{
532 struct s2255_fw *data = urb->context;
533 struct usb_device *udev = urb->dev;
534 int len;
Dean Anderson85b85482010-04-08 23:51:17 -0300535 dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
Dean Anderson38f993a2008-06-26 23:15:51 -0300536 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300537 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
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 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300544 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300545 atomic_set(&data->fw_state, S2255_FW_FAILED);
546 /* wake up anything waiting for the firmware */
547 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300548 return;
549 }
550#define CHUNK_SIZE 512
551 /* all USB transfers must be done with continuous kernel memory.
552 can't allocate more than 128k in current linux kernel, so
553 upload the firmware in chunks
554 */
555 if (data->fw_loaded < data->fw_size) {
556 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
557 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
558
559 if (len < CHUNK_SIZE)
560 memset(data->pfw_data, 0, CHUNK_SIZE);
561
562 dprintk(100, "completed len %d, loaded %d \n", len,
563 data->fw_loaded);
564
565 memcpy(data->pfw_data,
566 (char *) data->fw->data + data->fw_loaded, len);
567
568 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
569 data->pfw_data, CHUNK_SIZE,
570 s2255_fwchunk_complete, data);
571 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
572 dev_err(&udev->dev, "failed submit URB\n");
573 atomic_set(&data->fw_state, S2255_FW_FAILED);
574 /* wake up anything waiting for the firmware */
575 wake_up(&data->wait_fw);
576 return;
577 }
578 data->fw_loaded += len;
579 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300580 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson85b85482010-04-08 23:51:17 -0300581 dprintk(100, "%s: firmware upload complete\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300582 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300583 return;
584
585}
586
Dean Andersonfe85ce92010-06-01 19:12:07 -0300587static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300588{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300589 struct s2255_dmaqueue *dma_q = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300590 struct s2255_buffer *buf;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300591 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300592 unsigned long flags = 0;
593 int rc = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300594 spin_lock_irqsave(&dev->slock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300595 if (list_empty(&dma_q->active)) {
596 dprintk(1, "No active queue to serve\n");
597 rc = -1;
598 goto unlock;
599 }
600 buf = list_entry(dma_q->active.next,
601 struct s2255_buffer, vb.queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300602 list_del(&buf->vb.queue);
603 do_gettimeofday(&buf->vb.ts);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300604 s2255_fillbuff(channel, buf, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300605 wake_up(&buf->vb.done);
Dean Anderson85b85482010-04-08 23:51:17 -0300606 dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
Dean Anderson38f993a2008-06-26 23:15:51 -0300607unlock:
608 spin_unlock_irqrestore(&dev->slock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300609 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300610}
611
Dean Anderson38f993a2008-06-26 23:15:51 -0300612static const struct s2255_fmt *format_by_fourcc(int fourcc)
613{
614 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300615 for (i = 0; i < ARRAY_SIZE(formats); i++) {
616 if (-1 == formats[i].fourcc)
617 continue;
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300618 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
619 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
620 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300621 if (formats[i].fourcc == fourcc)
622 return formats + i;
623 }
624 return NULL;
625}
626
Dean Anderson38f993a2008-06-26 23:15:51 -0300627/* video buffer vmalloc implementation based partly on VIVI driver which is
628 * Copyright (c) 2006 by
629 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
630 * Ted Walther <ted--a.t--enumera.com>
631 * John Sokol <sokol--a.t--videotechnology.com>
632 * http://v4l.videotechnology.com/
633 *
634 */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300635static void s2255_fillbuff(struct s2255_channel *channel,
636 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300637{
638 int pos = 0;
639 struct timeval ts;
640 const char *tmpbuf;
641 char *vbuf = videobuf_to_vmalloc(&buf->vb);
642 unsigned long last_frame;
643 struct s2255_framei *frm;
644
645 if (!vbuf)
646 return;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300647 last_frame = channel->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300648 if (last_frame != -1) {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300649 frm = &channel->buffer.frame[last_frame];
Dean Anderson38f993a2008-06-26 23:15:51 -0300650 tmpbuf =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300651 (const char *)channel->buffer.frame[last_frame].lpvbits;
Dean Anderson38f993a2008-06-26 23:15:51 -0300652 switch (buf->fmt->fourcc) {
653 case V4L2_PIX_FMT_YUYV:
654 case V4L2_PIX_FMT_UYVY:
655 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
656 vbuf, buf->vb.width,
657 buf->vb.height,
658 buf->fmt->fourcc);
659 break;
660 case V4L2_PIX_FMT_GREY:
661 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
662 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300663 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300664 case V4L2_PIX_FMT_MJPEG:
Dean Anderson14d96262008-08-25 13:58:55 -0300665 buf->vb.size = jpgsize;
666 memcpy(vbuf, tmpbuf, buf->vb.size);
667 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300668 case V4L2_PIX_FMT_YUV422P:
669 memcpy(vbuf, tmpbuf,
670 buf->vb.width * buf->vb.height * 2);
671 break;
672 default:
673 printk(KERN_DEBUG "s2255: unknown format?\n");
674 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300675 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300676 } else {
677 printk(KERN_ERR "s2255: =======no frame\n");
678 return;
679
680 }
681 dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
682 (unsigned long)vbuf, pos);
683 /* tell v4l buffer was filled */
684
Dean Andersonfe85ce92010-06-01 19:12:07 -0300685 buf->vb.field_count = channel->frame_count * 2;
Dean Anderson38f993a2008-06-26 23:15:51 -0300686 do_gettimeofday(&ts);
687 buf->vb.ts = ts;
688 buf->vb.state = VIDEOBUF_DONE;
689}
690
691
692/* ------------------------------------------------------------------
693 Videobuf operations
694 ------------------------------------------------------------------*/
695
696static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
697 unsigned int *size)
698{
699 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300700 struct s2255_channel *channel = fh->channel;
701 *size = channel->width * channel->height * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300702
703 if (0 == *count)
704 *count = S2255_DEF_BUFS;
705
Andreas Bombedab7e312010-03-21 16:02:45 -0300706 if (*size * *count > vid_limit * 1024 * 1024)
707 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300708
709 return 0;
710}
711
712static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
713{
714 dprintk(4, "%s\n", __func__);
715
Dean Anderson38f993a2008-06-26 23:15:51 -0300716 videobuf_vmalloc_free(&buf->vb);
717 buf->vb.state = VIDEOBUF_NEEDS_INIT;
718}
719
720static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
721 enum v4l2_field field)
722{
723 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300724 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300725 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
726 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300727 int w = channel->width;
728 int h = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300729 dprintk(4, "%s, field=%d\n", __func__, field);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300730 if (channel->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300731 return -EINVAL;
732
Dean Andersonfe85ce92010-06-01 19:12:07 -0300733 if ((w < norm_minw(&channel->vdev)) ||
734 (w > norm_maxw(&channel->vdev)) ||
735 (h < norm_minh(&channel->vdev)) ||
736 (h > norm_maxh(&channel->vdev))) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300737 dprintk(4, "invalid buffer prepare\n");
738 return -EINVAL;
739 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300740 buf->vb.size = w * h * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300741 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
742 dprintk(4, "invalid buffer prepare\n");
743 return -EINVAL;
744 }
745
Dean Andersonfe85ce92010-06-01 19:12:07 -0300746 buf->fmt = channel->fmt;
747 buf->vb.width = w;
748 buf->vb.height = h;
Dean Anderson38f993a2008-06-26 23:15:51 -0300749 buf->vb.field = field;
750
Dean Anderson38f993a2008-06-26 23:15:51 -0300751 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
752 rc = videobuf_iolock(vq, &buf->vb, NULL);
753 if (rc < 0)
754 goto fail;
755 }
756
757 buf->vb.state = VIDEOBUF_PREPARED;
758 return 0;
759fail:
760 free_buffer(vq, buf);
761 return rc;
762}
763
764static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
765{
766 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
767 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300768 struct s2255_channel *channel = fh->channel;
769 struct s2255_dmaqueue *vidq = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300770 dprintk(1, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300771 buf->vb.state = VIDEOBUF_QUEUED;
772 list_add_tail(&buf->vb.queue, &vidq->active);
773}
774
775static void buffer_release(struct videobuf_queue *vq,
776 struct videobuf_buffer *vb)
777{
778 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
779 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300780 dprintk(4, "%s %d\n", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -0300781 free_buffer(vq, buf);
782}
783
784static struct videobuf_queue_ops s2255_video_qops = {
785 .buf_setup = buffer_setup,
786 .buf_prepare = buffer_prepare,
787 .buf_queue = buffer_queue,
788 .buf_release = buffer_release,
789};
790
791
Dean Andersonfe85ce92010-06-01 19:12:07 -0300792static int res_get(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300793{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300794 struct s2255_channel *channel = fh->channel;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300795 /* is it free? */
796 if (channel->resources)
797 return 0; /* no, someone else uses it */
Dean Anderson38f993a2008-06-26 23:15:51 -0300798 /* it's free, grab it */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300799 channel->resources = 1;
800 fh->resources = 1;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300801 dprintk(1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300802 return 1;
803}
804
Dean Andersonfe85ce92010-06-01 19:12:07 -0300805static int res_locked(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300806{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300807 return fh->channel->resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300808}
809
Dean Andersonf78d92c2008-07-22 14:43:27 -0300810static int res_check(struct s2255_fh *fh)
811{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300812 return fh->resources;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300813}
814
815
Dean Andersonfe85ce92010-06-01 19:12:07 -0300816static void res_free(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300817{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300818 struct s2255_channel *channel = fh->channel;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300819 channel->resources = 0;
820 fh->resources = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300821 dprintk(1, "res: put\n");
822}
823
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300824static int vidioc_querymenu(struct file *file, void *priv,
825 struct v4l2_querymenu *qmenu)
826{
827 static const char *colorfilter[] = {
828 "Off",
829 "On",
830 NULL
831 };
832 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
833 int i;
834 const char **menu_items = colorfilter;
835 for (i = 0; i < qmenu->index && menu_items[i]; i++)
836 ; /* do nothing (from v4l2-common.c) */
837 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
838 return -EINVAL;
839 strlcpy(qmenu->name, menu_items[qmenu->index],
840 sizeof(qmenu->name));
841 return 0;
842 }
843 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
844}
845
Dean Anderson38f993a2008-06-26 23:15:51 -0300846static int vidioc_querycap(struct file *file, void *priv,
847 struct v4l2_capability *cap)
848{
849 struct s2255_fh *fh = file->private_data;
850 struct s2255_dev *dev = fh->dev;
851 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
852 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300853 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Dean Anderson38f993a2008-06-26 23:15:51 -0300854 cap->version = S2255_VERSION;
855 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
856 return 0;
857}
858
859static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
860 struct v4l2_fmtdesc *f)
861{
862 int index = 0;
863 if (f)
864 index = f->index;
865
866 if (index >= ARRAY_SIZE(formats))
867 return -EINVAL;
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300868 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
869 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
870 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300871 dprintk(4, "name %s\n", formats[index].name);
872 strlcpy(f->description, formats[index].name, sizeof(f->description));
873 f->pixelformat = formats[index].fourcc;
874 return 0;
875}
876
877static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
878 struct v4l2_format *f)
879{
880 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300881 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300882
Dean Andersonfe85ce92010-06-01 19:12:07 -0300883 f->fmt.pix.width = channel->width;
884 f->fmt.pix.height = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300885 f->fmt.pix.field = fh->vb_vidq.field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300886 f->fmt.pix.pixelformat = channel->fmt->fourcc;
887 f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300888 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300889 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300890}
891
892static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
893 struct v4l2_format *f)
894{
895 const struct s2255_fmt *fmt;
896 enum v4l2_field field;
897 int b_any_field = 0;
898 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300899 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300900 int is_ntsc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300901 is_ntsc =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300902 (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300903
904 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
905
906 if (fmt == NULL)
907 return -EINVAL;
908
909 field = f->fmt.pix.field;
910 if (field == V4L2_FIELD_ANY)
911 b_any_field = 1;
912
Dean Anderson85b85482010-04-08 23:51:17 -0300913 dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
914 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300915 if (is_ntsc) {
916 /* NTSC */
917 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
918 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
919 if (b_any_field) {
920 field = V4L2_FIELD_SEQ_TB;
921 } else if (!((field == V4L2_FIELD_INTERLACED) ||
922 (field == V4L2_FIELD_SEQ_TB) ||
923 (field == V4L2_FIELD_INTERLACED_TB))) {
924 dprintk(1, "unsupported field setting\n");
925 return -EINVAL;
926 }
927 } else {
928 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
929 if (b_any_field) {
930 field = V4L2_FIELD_TOP;
931 } else if (!((field == V4L2_FIELD_TOP) ||
932 (field == V4L2_FIELD_BOTTOM))) {
933 dprintk(1, "unsupported field setting\n");
934 return -EINVAL;
935 }
936
937 }
938 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
939 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
940 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
941 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
942 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
943 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
944 else
945 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
946 } else {
947 /* PAL */
948 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
949 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
950 if (b_any_field) {
951 field = V4L2_FIELD_SEQ_TB;
952 } else if (!((field == V4L2_FIELD_INTERLACED) ||
953 (field == V4L2_FIELD_SEQ_TB) ||
954 (field == V4L2_FIELD_INTERLACED_TB))) {
955 dprintk(1, "unsupported field setting\n");
956 return -EINVAL;
957 }
958 } else {
959 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
960 if (b_any_field) {
961 field = V4L2_FIELD_TOP;
962 } else if (!((field == V4L2_FIELD_TOP) ||
963 (field == V4L2_FIELD_BOTTOM))) {
964 dprintk(1, "unsupported field setting\n");
965 return -EINVAL;
966 }
967 }
968 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300969 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
970 field = V4L2_FIELD_SEQ_TB;
971 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300972 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
973 field = V4L2_FIELD_TOP;
974 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300975 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
976 field = V4L2_FIELD_TOP;
977 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300978 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
979 field = V4L2_FIELD_TOP;
980 }
981 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300982 f->fmt.pix.field = field;
983 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
984 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson85b85482010-04-08 23:51:17 -0300985 dprintk(50, "%s: set width %d height %d field %d\n", __func__,
986 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300987 return 0;
988}
989
990static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
991 struct v4l2_format *f)
992{
993 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300994 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300995 const struct s2255_fmt *fmt;
996 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300997 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300998 int ret;
999 int norm;
1000
1001 ret = vidioc_try_fmt_vid_cap(file, fh, f);
1002
1003 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001004 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001005
1006 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1007
1008 if (fmt == NULL)
1009 return -EINVAL;
1010
1011 mutex_lock(&q->vb_lock);
1012
1013 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1014 dprintk(1, "queue busy\n");
1015 ret = -EBUSY;
1016 goto out_s_fmt;
1017 }
1018
Dean Andersonfe85ce92010-06-01 19:12:07 -03001019 if (res_locked(fh)) {
Dean Anderson85b85482010-04-08 23:51:17 -03001020 dprintk(1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001021 ret = -EBUSY;
1022 goto out_s_fmt;
1023 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001024 mode = channel->mode;
1025 channel->fmt = fmt;
1026 channel->width = f->fmt.pix.width;
1027 channel->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -03001028 fh->vb_vidq.field = f->fmt.pix.field;
1029 fh->type = f->type;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001030 norm = norm_minw(&channel->vdev);
1031 if (channel->width > norm_minw(&channel->vdev)) {
1032 if (channel->height > norm_minh(&channel->vdev)) {
1033 if (channel->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -03001034 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001035 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -03001036 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001037 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -03001038 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001039 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001040
1041 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001042 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001043 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001044 /* color mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001045 switch (channel->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001046 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001047 mode.color &= ~MASK_COLOR;
1048 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001049 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001050 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -03001051 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001052 mode.color &= ~MASK_COLOR;
1053 mode.color |= COLOR_JPG;
1054 mode.color |= (channel->jc.quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001055 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001056 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001057 mode.color &= ~MASK_COLOR;
1058 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001059 break;
1060 case V4L2_PIX_FMT_YUYV:
1061 case V4L2_PIX_FMT_UYVY:
1062 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001063 mode.color &= ~MASK_COLOR;
1064 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001065 break;
1066 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001067 if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
1068 mode.restart = 1;
1069 else if (mode.scale != channel->mode.scale)
1070 mode.restart = 1;
1071 else if (mode.format != channel->mode.format)
1072 mode.restart = 1;
1073 channel->mode = mode;
1074 (void) s2255_set_mode(channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001075 ret = 0;
1076out_s_fmt:
1077 mutex_unlock(&q->vb_lock);
1078 return ret;
1079}
1080
1081static int vidioc_reqbufs(struct file *file, void *priv,
1082 struct v4l2_requestbuffers *p)
1083{
1084 int rc;
1085 struct s2255_fh *fh = priv;
1086 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1087 return rc;
1088}
1089
1090static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1091{
1092 int rc;
1093 struct s2255_fh *fh = priv;
1094 rc = videobuf_querybuf(&fh->vb_vidq, p);
1095 return rc;
1096}
1097
1098static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1099{
1100 int rc;
1101 struct s2255_fh *fh = priv;
1102 rc = videobuf_qbuf(&fh->vb_vidq, p);
1103 return rc;
1104}
1105
1106static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1107{
1108 int rc;
1109 struct s2255_fh *fh = priv;
1110 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1111 return rc;
1112}
1113
Dean Anderson38f993a2008-06-26 23:15:51 -03001114/* write to the configuration pipe, synchronously */
1115static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1116 int size)
1117{
1118 int pipe;
1119 int done;
1120 long retval = -1;
1121 if (udev) {
1122 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1123 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1124 }
1125 return retval;
1126}
1127
1128static u32 get_transfer_size(struct s2255_mode *mode)
1129{
1130 int linesPerFrame = LINE_SZ_DEF;
1131 int pixelsPerLine = NUM_LINES_DEF;
1132 u32 outImageSize;
1133 u32 usbInSize;
1134 unsigned int mask_mult;
1135
1136 if (mode == NULL)
1137 return 0;
1138
1139 if (mode->format == FORMAT_NTSC) {
1140 switch (mode->scale) {
1141 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001142 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001143 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1144 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1145 break;
1146 case SCALE_2CIFS:
1147 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1148 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1149 break;
1150 case SCALE_1CIFS:
1151 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1152 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1153 break;
1154 default:
1155 break;
1156 }
1157 } else if (mode->format == FORMAT_PAL) {
1158 switch (mode->scale) {
1159 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001160 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001161 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1162 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1163 break;
1164 case SCALE_2CIFS:
1165 linesPerFrame = NUM_LINES_2CIFS_PAL;
1166 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1167 break;
1168 case SCALE_1CIFS:
1169 linesPerFrame = NUM_LINES_1CIFS_PAL;
1170 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1171 break;
1172 default:
1173 break;
1174 }
1175 }
1176 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001177 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001178 /* 2 bytes/pixel if not monochrome */
1179 outImageSize *= 2;
1180 }
1181
1182 /* total bytes to send including prefix and 4K padding;
1183 must be a multiple of USB_READ_SIZE */
1184 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1185 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1186 /* if size not a multiple of USB_READ_SIZE */
1187 if (usbInSize & ~mask_mult)
1188 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1189 return usbInSize;
1190}
1191
Dean Anderson85b85482010-04-08 23:51:17 -03001192static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001193{
1194 struct device *dev = &sdev->udev->dev;
1195 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001196 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1197 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001198 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001199 dev_info(dev, "------------------------------------------------\n");
1200}
1201
1202/*
1203 * set mode is the function which controls the DSP.
1204 * the restart parameter in struct s2255_mode should be set whenever
1205 * the image size could change via color format, video system or image
1206 * size.
1207 * When the restart parameter is set, we sleep for ONE frame to allow the
1208 * DSP time to get the new frame
1209 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001210static int s2255_set_mode(struct s2255_channel *channel,
Dean Anderson38f993a2008-06-26 23:15:51 -03001211 struct s2255_mode *mode)
1212{
1213 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001214 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001215 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001216 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001217 chn_rev = G_chnmap[channel->idx];
1218 dprintk(3, "%s channel: %d\n", __func__, channel->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001219 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001220 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1221 mode->color &= ~MASK_COLOR;
1222 mode->color |= COLOR_JPG;
1223 mode->color &= ~MASK_JPG_QUALITY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001224 mode->color |= (channel->jc.quality << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001225 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001226 /* save the mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001227 channel->mode = *mode;
1228 channel->req_image_size = get_transfer_size(mode);
1229 dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001230 buffer = kzalloc(512, GFP_KERNEL);
1231 if (buffer == NULL) {
1232 dev_err(&dev->udev->dev, "out of mem\n");
1233 return -ENOMEM;
1234 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001235 /* set the mode */
1236 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001237 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001238 buffer[2] = CMD_SET_MODE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001239 memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
1240 channel->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001241 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1242 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001243 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001244 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001245 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001246 if (mode->restart) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001247 wait_event_timeout(channel->wait_setmode,
1248 (channel->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001249 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001250 if (channel->setmode_ready != 1) {
Dean Anderson14d96262008-08-25 13:58:55 -03001251 printk(KERN_DEBUG "s2255: no set mode response\n");
1252 res = -EFAULT;
1253 }
1254 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001255 /* clear the restart flag */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001256 channel->mode.restart = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001257 dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001258 return res;
1259}
1260
Dean Andersonfe85ce92010-06-01 19:12:07 -03001261static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001262{
1263 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001264 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001265 u32 chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001266 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001267 chn_rev = G_chnmap[channel->idx];
1268 dprintk(4, "%s chan %d\n", __func__, channel->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001269 buffer = kzalloc(512, GFP_KERNEL);
1270 if (buffer == NULL) {
1271 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001272 return -ENOMEM;
1273 }
1274 /* form the get vid status command */
1275 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001276 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001277 buffer[2] = CMD_STATUS;
1278 *pstatus = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001279 channel->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001280 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1281 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001282 wait_event_timeout(channel->wait_vidstatus,
1283 (channel->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001284 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001285 if (channel->vidstatus_ready != 1) {
Dean Anderson4de39f52010-03-03 19:39:19 -03001286 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1287 res = -EFAULT;
1288 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001289 *pstatus = channel->vidstatus;
Dean Anderson4de39f52010-03-03 19:39:19 -03001290 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03001291 return res;
1292}
1293
Dean Anderson38f993a2008-06-26 23:15:51 -03001294static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1295{
1296 int res;
1297 struct s2255_fh *fh = priv;
1298 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001299 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001300 int j;
1301 dprintk(4, "%s\n", __func__);
1302 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1303 dev_err(&dev->udev->dev, "invalid fh type0\n");
1304 return -EINVAL;
1305 }
1306 if (i != fh->type) {
1307 dev_err(&dev->udev->dev, "invalid fh type1\n");
1308 return -EINVAL;
1309 }
1310
Dean Andersonfe85ce92010-06-01 19:12:07 -03001311 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001312 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001313 return -EBUSY;
1314 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001315 channel->last_frame = -1;
1316 channel->bad_payload = 0;
1317 channel->cur_frame = 0;
1318 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001319 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001320 channel->buffer.frame[j].ulState = S2255_READ_IDLE;
1321 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001322 }
1323 res = videobuf_streamon(&fh->vb_vidq);
1324 if (res == 0) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001325 s2255_start_acquire(channel);
1326 channel->b_acquire = 1;
1327 } else
1328 res_free(fh);
1329
Dean Anderson38f993a2008-06-26 23:15:51 -03001330 return res;
1331}
1332
1333static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1334{
Dean Anderson38f993a2008-06-26 23:15:51 -03001335 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001336 dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001337 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1338 printk(KERN_ERR "invalid fh type0\n");
1339 return -EINVAL;
1340 }
1341 if (i != fh->type) {
1342 printk(KERN_ERR "invalid type i\n");
1343 return -EINVAL;
1344 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001345 s2255_stop_acquire(fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001346 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001347 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001348 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001349}
1350
1351static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1352{
1353 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001354 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001355 struct videobuf_queue *q = &fh->vb_vidq;
1356 int ret = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001357 mutex_lock(&q->vb_lock);
1358 if (videobuf_queue_is_busy(q)) {
1359 dprintk(1, "queue busy\n");
1360 ret = -EBUSY;
1361 goto out_s_std;
1362 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001363 if (res_locked(fh)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001364 dprintk(1, "can't change standard after started\n");
1365 ret = -EBUSY;
1366 goto out_s_std;
1367 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001368 mode = fh->channel->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001369 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001370 dprintk(4, "%s NTSC\n", __func__);
1371 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001372 if (mode.format != FORMAT_NTSC) {
1373 mode.restart = 1;
1374 mode.format = FORMAT_NTSC;
1375 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001376 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001377 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001378 dprintk(4, "%s PAL\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001379 if (mode.format != FORMAT_PAL) {
1380 mode.restart = 1;
1381 mode.format = FORMAT_PAL;
1382 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001383 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001384 } else {
1385 ret = -EINVAL;
1386 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001387 if (mode.restart)
1388 s2255_set_mode(fh->channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001389out_s_std:
1390 mutex_unlock(&q->vb_lock);
1391 return ret;
1392}
1393
1394/* Sensoray 2255 is a multiple channel capture device.
1395 It does not have a "crossbar" of inputs.
1396 We use one V4L device per channel. The user must
1397 be aware that certain combinations are not allowed.
1398 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1399 at once in color(you can do full fps on 4 channels with greyscale.
1400*/
1401static int vidioc_enum_input(struct file *file, void *priv,
1402 struct v4l2_input *inp)
1403{
Dean Anderson4de39f52010-03-03 19:39:19 -03001404 struct s2255_fh *fh = priv;
1405 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001406 struct s2255_channel *channel = fh->channel;
Dean Anderson4de39f52010-03-03 19:39:19 -03001407 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001408 if (inp->index != 0)
1409 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001410 inp->type = V4L2_INPUT_TYPE_CAMERA;
1411 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001412 inp->status = 0;
1413 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1414 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001415 rc = s2255_cmd_status(fh->channel, &status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001416 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1417 if (rc == 0)
1418 inp->status = (status & 0x01) ? 0
1419 : V4L2_IN_ST_NO_SIGNAL;
1420 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001421 switch (dev->pid) {
1422 case 0x2255:
1423 default:
1424 strlcpy(inp->name, "Composite", sizeof(inp->name));
1425 break;
1426 case 0x2257:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001427 strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001428 sizeof(inp->name));
1429 break;
1430 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001431 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001432}
1433
1434static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1435{
1436 *i = 0;
1437 return 0;
1438}
1439static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1440{
1441 if (i > 0)
1442 return -EINVAL;
1443 return 0;
1444}
1445
1446/* --- controls ---------------------------------------------- */
1447static int vidioc_queryctrl(struct file *file, void *priv,
1448 struct v4l2_queryctrl *qc)
1449{
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001450 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001451 struct s2255_channel *channel = fh->channel;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001452 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001453 switch (qc->id) {
1454 case V4L2_CID_BRIGHTNESS:
1455 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1456 break;
1457 case V4L2_CID_CONTRAST:
1458 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1459 break;
1460 case V4L2_CID_SATURATION:
1461 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1462 break;
1463 case V4L2_CID_HUE:
1464 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1465 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001466 case V4L2_CID_PRIVATE_COLORFILTER:
1467 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1468 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001469 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001470 return -EINVAL;
1471 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1472 qc->type = V4L2_CTRL_TYPE_MENU;
1473 qc->minimum = 0;
1474 qc->maximum = 1;
1475 qc->step = 1;
1476 qc->default_value = 1;
1477 qc->flags = 0;
1478 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001479 default:
1480 return -EINVAL;
1481 }
1482 dprintk(4, "%s, id %d\n", __func__, qc->id);
1483 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001484}
1485
1486static int vidioc_g_ctrl(struct file *file, void *priv,
1487 struct v4l2_control *ctrl)
1488{
Dean Anderson2e70db92010-03-05 14:29:09 -03001489 struct s2255_fh *fh = priv;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001490 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001491 struct s2255_channel *channel = fh->channel;
Dean Anderson2e70db92010-03-05 14:29:09 -03001492 switch (ctrl->id) {
1493 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001494 ctrl->value = channel->mode.bright;
Dean Anderson2e70db92010-03-05 14:29:09 -03001495 break;
1496 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001497 ctrl->value = channel->mode.contrast;
Dean Anderson2e70db92010-03-05 14:29:09 -03001498 break;
1499 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001500 ctrl->value = channel->mode.saturation;
Dean Anderson2e70db92010-03-05 14:29:09 -03001501 break;
1502 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001503 ctrl->value = channel->mode.hue;
Dean Anderson2e70db92010-03-05 14:29:09 -03001504 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001505 case V4L2_CID_PRIVATE_COLORFILTER:
1506 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1507 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001508 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001509 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001510 ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001511 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001512 default:
1513 return -EINVAL;
1514 }
1515 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1516 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001517}
1518
1519static int vidioc_s_ctrl(struct file *file, void *priv,
1520 struct v4l2_control *ctrl)
1521{
Dean Anderson38f993a2008-06-26 23:15:51 -03001522 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001523 struct s2255_channel *channel = fh->channel;
1524 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
1525 struct s2255_mode mode;
1526 mode = channel->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001527 dprintk(4, "%s\n", __func__);
1528 /* update the mode to the corresponding value */
1529 switch (ctrl->id) {
1530 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001531 mode.bright = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001532 break;
1533 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001534 mode.contrast = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001535 break;
1536 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001537 mode.hue = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001538 break;
1539 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001540 mode.saturation = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001541 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001542 case V4L2_CID_PRIVATE_COLORFILTER:
1543 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1544 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001545 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001546 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001547 mode.color &= ~MASK_INPUT_TYPE;
1548 mode.color |= ((ctrl->value ? 0 : 1) << 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001549 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001550 default:
1551 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001552 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001553 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001554 /* set mode here. Note: stream does not need restarted.
1555 some V4L programs restart stream unnecessarily
1556 after a s_crtl.
1557 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001558 s2255_set_mode(fh->channel, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001559 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001560}
1561
Dean Anderson22b88d42008-08-29 15:33:19 -03001562static int vidioc_g_jpegcomp(struct file *file, void *priv,
1563 struct v4l2_jpegcompression *jc)
1564{
1565 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001566 struct s2255_channel *channel = fh->channel;
1567 *jc = channel->jc;
Dean Anderson85b85482010-04-08 23:51:17 -03001568 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001569 return 0;
1570}
1571
1572static int vidioc_s_jpegcomp(struct file *file, void *priv,
1573 struct v4l2_jpegcompression *jc)
1574{
1575 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001576 struct s2255_channel *channel = fh->channel;
Dean Anderson22b88d42008-08-29 15:33:19 -03001577 if (jc->quality < 0 || jc->quality > 100)
1578 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001579 channel->jc.quality = jc->quality;
Dean Anderson85b85482010-04-08 23:51:17 -03001580 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001581 return 0;
1582}
Dean Anderson7d853532009-05-15 14:32:04 -03001583
1584static int vidioc_g_parm(struct file *file, void *priv,
1585 struct v4l2_streamparm *sp)
1586{
1587 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001588 __u32 def_num, def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001589 struct s2255_channel *channel = fh->channel;
Dean Anderson7d853532009-05-15 14:32:04 -03001590 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1591 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001592 memset(sp, 0, sizeof(struct v4l2_streamparm));
1593 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001594 sp->parm.capture.capturemode = channel->cap_parm.capturemode;
1595 def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1596 def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001597 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001598 switch (channel->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001599 default:
1600 case FDEC_1:
1601 sp->parm.capture.timeperframe.numerator = def_num;
1602 break;
1603 case FDEC_2:
1604 sp->parm.capture.timeperframe.numerator = def_num * 2;
1605 break;
1606 case FDEC_3:
1607 sp->parm.capture.timeperframe.numerator = def_num * 3;
1608 break;
1609 case FDEC_5:
1610 sp->parm.capture.timeperframe.numerator = def_num * 5;
1611 break;
1612 }
1613 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1614 sp->parm.capture.capturemode,
1615 sp->parm.capture.timeperframe.numerator,
1616 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001617 return 0;
1618}
1619
1620static int vidioc_s_parm(struct file *file, void *priv,
1621 struct v4l2_streamparm *sp)
1622{
1623 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001624 struct s2255_channel *channel = fh->channel;
1625 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001626 int fdec = FDEC_1;
1627 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001628 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1629 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001630 mode = channel->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001631 /* high quality capture mode requires a stream restart */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001632 if (channel->cap_parm.capturemode
1633 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001634 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001635 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1636 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001637 if (def_dem != sp->parm.capture.timeperframe.denominator)
1638 sp->parm.capture.timeperframe.numerator = def_num;
1639 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1640 sp->parm.capture.timeperframe.numerator = def_num;
1641 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1642 sp->parm.capture.timeperframe.numerator = def_num * 2;
1643 fdec = FDEC_2;
1644 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1645 sp->parm.capture.timeperframe.numerator = def_num * 3;
1646 fdec = FDEC_3;
1647 } else {
1648 sp->parm.capture.timeperframe.numerator = def_num * 5;
1649 fdec = FDEC_5;
1650 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001651 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001652 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001653 s2255_set_mode(channel, &mode);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001654 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1655 __func__,
1656 sp->parm.capture.capturemode,
1657 sp->parm.capture.timeperframe.numerator,
1658 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001659 return 0;
1660}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001661
1662static int vidioc_enum_frameintervals(struct file *file, void *priv,
1663 struct v4l2_frmivalenum *fe)
1664{
1665 int is_ntsc = 0;
1666#define NUM_FRAME_ENUMS 4
1667 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
1668 if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
1669 return -EINVAL;
1670 switch (fe->width) {
1671 case 640:
1672 if (fe->height != 240 && fe->height != 480)
1673 return -EINVAL;
1674 is_ntsc = 1;
1675 break;
1676 case 320:
1677 if (fe->height != 240)
1678 return -EINVAL;
1679 is_ntsc = 1;
1680 break;
1681 case 704:
1682 if (fe->height != 288 && fe->height != 576)
1683 return -EINVAL;
1684 break;
1685 case 352:
1686 if (fe->height != 288)
1687 return -EINVAL;
1688 break;
1689 default:
1690 return -EINVAL;
1691 }
1692 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1693 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1694 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1695 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1696 fe->discrete.denominator);
1697 return 0;
1698}
1699
Hans Verkuilbec43662008-12-30 06:58:20 -03001700static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001701{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001702 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001703 struct s2255_channel *channel = video_drvdata(file);
1704 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001705 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001706 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001707 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001708 dprintk(1, "s2255: open called (dev=%s)\n",
1709 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001710 /*
1711 * open lock necessary to prevent multiple instances
1712 * of v4l-conf (or other programs) from simultaneously
1713 * reloading firmware.
1714 */
Dean Anderson38f993a2008-06-26 23:15:51 -03001715 mutex_lock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001716 state = atomic_read(&dev->fw_data->fw_state);
1717 switch (state) {
1718 case S2255_FW_DISCONNECTING:
1719 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001720 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001721 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001722 s2255_dev_err(&dev->udev->dev,
1723 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001724 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001725 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001726 ((atomic_read(&dev->fw_data->fw_state)
1727 == S2255_FW_SUCCESS) ||
1728 (atomic_read(&dev->fw_data->fw_state)
1729 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001730 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001731 /* state may have changed, re-read */
1732 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001733 break;
1734 case S2255_FW_NOTLOADED:
1735 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001736 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1737 driver loaded and then device immediately opened */
1738 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1739 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001740 ((atomic_read(&dev->fw_data->fw_state)
1741 == S2255_FW_SUCCESS) ||
1742 (atomic_read(&dev->fw_data->fw_state)
1743 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001744 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001745 /* state may have changed, re-read */
1746 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001747 break;
1748 case S2255_FW_SUCCESS:
1749 default:
1750 break;
1751 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001752 /* state may have changed in above switch statement */
1753 switch (state) {
1754 case S2255_FW_SUCCESS:
1755 break;
1756 case S2255_FW_FAILED:
1757 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Andersoneb78dee2010-04-12 15:05:37 -03001758 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001759 return -ENODEV;
1760 case S2255_FW_DISCONNECTING:
1761 printk(KERN_INFO "%s: disconnecting\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001762 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001763 return -ENODEV;
1764 case S2255_FW_LOADED_DSPWAIT:
1765 case S2255_FW_NOTLOADED:
1766 printk(KERN_INFO "%s: firmware not loaded yet"
1767 "please try again later\n",
1768 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001769 /*
1770 * Timeout on firmware load means device unusable.
1771 * Set firmware failure state.
1772 * On next s2255_open the firmware will be reloaded.
1773 */
1774 atomic_set(&dev->fw_data->fw_state,
1775 S2255_FW_FAILED);
1776 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001777 return -EAGAIN;
1778 default:
1779 printk(KERN_INFO "%s: unknown state\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001780 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001781 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001782 }
Dean Andersoneb78dee2010-04-12 15:05:37 -03001783 mutex_unlock(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001784 /* allocate + initialize per filehandle data */
1785 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001786 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001787 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03001788 file->private_data = fh;
1789 fh->dev = dev;
1790 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001791 fh->channel = channel;
1792 if (!channel->configured) {
1793 /* configure channel to default state */
1794 channel->fmt = &formats[0];
1795 s2255_set_mode(channel, &channel->mode);
1796 channel->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001797 }
Dean Anderson85b85482010-04-08 23:51:17 -03001798 dprintk(1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001799 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson85b85482010-04-08 23:51:17 -03001800 dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001801 (unsigned long)fh, (unsigned long)dev,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001802 (unsigned long)&channel->vidq);
Dean Anderson85b85482010-04-08 23:51:17 -03001803 dprintk(4, "%s: list_empty active=%d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001804 list_empty(&channel->vidq.active));
Dean Anderson38f993a2008-06-26 23:15:51 -03001805 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1806 NULL, &dev->slock,
1807 fh->type,
1808 V4L2_FIELD_INTERLACED,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001809 sizeof(struct s2255_buffer),
1810 fh, vdev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001811 return 0;
1812}
1813
1814
1815static unsigned int s2255_poll(struct file *file,
1816 struct poll_table_struct *wait)
1817{
1818 struct s2255_fh *fh = file->private_data;
1819 int rc;
1820 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001821 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1822 return POLLERR;
Dean Anderson38f993a2008-06-26 23:15:51 -03001823 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
1824 return rc;
1825}
1826
Dean Andersond62e85a2010-04-09 19:54:26 -03001827static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001828{
Dean Anderson38f993a2008-06-26 23:15:51 -03001829 /* board shutdown stops the read pipe if it is running */
1830 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001831 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001832 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001833 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001834 usb_kill_urb(dev->fw_data->fw_urb);
1835 usb_free_urb(dev->fw_data->fw_urb);
1836 dev->fw_data->fw_urb = NULL;
1837 }
Dean Andersonf78d92c2008-07-22 14:43:27 -03001838 if (dev->fw_data->fw)
1839 release_firmware(dev->fw_data->fw);
1840 kfree(dev->fw_data->pfw_data);
1841 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001842 /* reset the DSP so firmware can be reloaded next time */
1843 s2255_reset_dsppower(dev);
1844 mutex_destroy(&dev->open_lock);
1845 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001846 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001847 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001848 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001849 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001850}
1851
Dean Andersonff7e22d2010-04-08 23:38:07 -03001852static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001853{
1854 struct s2255_fh *fh = file->private_data;
1855 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001856 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001857 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001858 if (!dev)
1859 return -ENODEV;
Dean Andersonf78d92c2008-07-22 14:43:27 -03001860 /* turn off stream */
1861 if (res_check(fh)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001862 if (channel->b_acquire)
1863 s2255_stop_acquire(fh->channel);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001864 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001865 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001866 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001867 videobuf_mmap_free(&fh->vb_vidq);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001868 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001869 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001870 return 0;
1871}
1872
1873static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1874{
1875 struct s2255_fh *fh = file->private_data;
1876 int ret;
1877
1878 if (!fh)
1879 return -ENODEV;
Dean Anderson85b85482010-04-08 23:51:17 -03001880 dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Dean Anderson38f993a2008-06-26 23:15:51 -03001881 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
Dean Anderson85b85482010-04-08 23:51:17 -03001882 dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001883 (unsigned long)vma->vm_start,
1884 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001885 return ret;
1886}
1887
Hans Verkuilbec43662008-12-30 06:58:20 -03001888static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001889 .owner = THIS_MODULE,
1890 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001891 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001892 .poll = s2255_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001893 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001894 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001895};
1896
Hans Verkuila3998102008-07-21 02:57:38 -03001897static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001898 .vidioc_querymenu = vidioc_querymenu,
Dean Anderson38f993a2008-06-26 23:15:51 -03001899 .vidioc_querycap = vidioc_querycap,
1900 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1901 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1902 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1903 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1904 .vidioc_reqbufs = vidioc_reqbufs,
1905 .vidioc_querybuf = vidioc_querybuf,
1906 .vidioc_qbuf = vidioc_qbuf,
1907 .vidioc_dqbuf = vidioc_dqbuf,
1908 .vidioc_s_std = vidioc_s_std,
1909 .vidioc_enum_input = vidioc_enum_input,
1910 .vidioc_g_input = vidioc_g_input,
1911 .vidioc_s_input = vidioc_s_input,
1912 .vidioc_queryctrl = vidioc_queryctrl,
1913 .vidioc_g_ctrl = vidioc_g_ctrl,
1914 .vidioc_s_ctrl = vidioc_s_ctrl,
1915 .vidioc_streamon = vidioc_streamon,
1916 .vidioc_streamoff = vidioc_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001917 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1918 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001919 .vidioc_s_parm = vidioc_s_parm,
1920 .vidioc_g_parm = vidioc_g_parm,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001921 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuila3998102008-07-21 02:57:38 -03001922};
1923
Dean Andersonff7e22d2010-04-08 23:38:07 -03001924static void s2255_video_device_release(struct video_device *vdev)
1925{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001926 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
1927 dprintk(4, "%s, chnls: %d \n", __func__,
1928 atomic_read(&dev->num_channels));
1929 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001930 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001931 return;
1932}
1933
Hans Verkuila3998102008-07-21 02:57:38 -03001934static struct video_device template = {
1935 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001936 .fops = &s2255_fops_v4l,
1937 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001938 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001939 .tvnorms = S2255_NORMS,
1940 .current_norm = V4L2_STD_NTSC_M,
1941};
1942
1943static int s2255_probe_v4l(struct s2255_dev *dev)
1944{
1945 int ret;
1946 int i;
1947 int cur_nr = video_nr;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001948 struct s2255_channel *channel;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001949 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1950 if (ret)
1951 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001952 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001953 /* register 4 video devices */
1954 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001955 channel = &dev->channel[i];
1956 INIT_LIST_HEAD(&channel->vidq.active);
1957 channel->vidq.dev = dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001958 /* register 4 video devices */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001959 channel->vdev = template;
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001960 channel->vdev.lock = &dev->lock;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001961 channel->vdev.v4l2_dev = &dev->v4l2_dev;
1962 video_set_drvdata(&channel->vdev, channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03001963 if (video_nr == -1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001964 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001965 VFL_TYPE_GRABBER,
1966 video_nr);
1967 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001968 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001969 VFL_TYPE_GRABBER,
1970 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001971
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001972 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001973 dev_err(&dev->udev->dev,
1974 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001975 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001976 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001977 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001978 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001979 video_device_node_name(&channel->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001980
Dean Anderson38f993a2008-06-26 23:15:51 -03001981 }
Dean Andersonabce21f2009-04-23 16:04:41 -03001982 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
1983 S2255_MAJOR_VERSION,
1984 S2255_MINOR_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001985 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001986 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001987 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001988 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001989 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001990 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001991 printk(KERN_WARNING "s2255: Not all channels available.\n");
1992 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001993}
1994
Dean Anderson38f993a2008-06-26 23:15:51 -03001995/* this function moves the usb stream read pipe data
1996 * into the system buffers.
1997 * returns 0 on success, EAGAIN if more data to process( call this
1998 * function again).
1999 *
2000 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03002001 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03002002 * bytes 4-7: channel: 0-3
2003 * bytes 8-11: payload size: size of the frame
2004 * bytes 12-payloadsize+12: frame data
2005 */
2006static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
2007{
Dean Anderson38f993a2008-06-26 23:15:51 -03002008 char *pdest;
2009 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002010 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002011 char *psrc;
2012 unsigned long copy_size;
2013 unsigned long size;
2014 s32 idx = -1;
2015 struct s2255_framei *frm;
2016 unsigned char *pdata;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002017 struct s2255_channel *channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03002018 dprintk(100, "buffer to user\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002019 channel = &dev->channel[dev->cc];
2020 idx = channel->cur_frame;
2021 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002022 if (frm->ulState == S2255_READ_IDLE) {
2023 int jj;
2024 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03002025 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03002026 int payload;
2027 /* search for marker codes */
2028 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03002029 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002030 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03002031 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03002032 case S2255_MARKER_FRAME:
Dean Anderson14d96262008-08-25 13:58:55 -03002033 dprintk(4, "found frame marker at offset:"
2034 " %d [%x %x]\n", jj, pdata[0],
2035 pdata[1]);
2036 offset = jj + PREFIX_SIZE;
2037 bframe = 1;
2038 cc = pdword[1];
2039 if (cc >= MAX_CHANNELS) {
2040 printk(KERN_ERR
2041 "bad channel\n");
2042 return -EINVAL;
2043 }
2044 /* reverse it */
2045 dev->cc = G_chnmap[cc];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002046 channel = &dev->channel[dev->cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002047 payload = pdword[3];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002048 if (payload > channel->req_image_size) {
2049 channel->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03002050 /* discard the bad frame */
2051 return -EINVAL;
2052 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002053 channel->pkt_size = payload;
2054 channel->jpg_size = pdword[4];
Dean Anderson14d96262008-08-25 13:58:55 -03002055 break;
2056 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002057
Dean Anderson14d96262008-08-25 13:58:55 -03002058 pdata += DEF_USB_BLOCK;
2059 jj += DEF_USB_BLOCK;
2060 if (pdword[1] >= MAX_CHANNELS)
2061 break;
2062 cc = G_chnmap[pdword[1]];
Roel Kluinf14a2972009-10-23 07:59:42 -03002063 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002064 break;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002065 channel = &dev->channel[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002066 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03002067 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03002068 /* check if channel valid */
2069 /* set mode ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002070 channel->setmode_ready = 1;
2071 wake_up(&channel->wait_setmode);
Dean Anderson14d96262008-08-25 13:58:55 -03002072 dprintk(5, "setmode ready %d\n", cc);
2073 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002074 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002075 dev->chn_ready |= (1 << cc);
2076 if ((dev->chn_ready & 0x0f) != 0x0f)
2077 break;
2078 /* all channels ready */
2079 printk(KERN_INFO "s2255: fw loaded\n");
2080 atomic_set(&dev->fw_data->fw_state,
2081 S2255_FW_SUCCESS);
2082 wake_up(&dev->fw_data->wait_fw);
2083 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002084 case S2255_RESPONSE_STATUS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002085 channel->vidstatus = pdword[3];
2086 channel->vidstatus_ready = 1;
2087 wake_up(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002088 dprintk(5, "got vidstatus %x chan %d\n",
2089 pdword[3], cc);
2090 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002091 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02002092 printk(KERN_INFO "s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002093 }
2094 default:
2095 pdata++;
2096 break;
2097 }
2098 if (bframe)
2099 break;
2100 } /* for */
2101 if (!bframe)
2102 return -EINVAL;
2103 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002104 channel = &dev->channel[dev->cc];
2105 idx = channel->cur_frame;
2106 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002107 /* search done. now find out if should be acquiring on this channel */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002108 if (!channel->b_acquire) {
Dean Anderson14d96262008-08-25 13:58:55 -03002109 /* we found a frame, but this channel is turned off */
2110 frm->ulState = S2255_READ_IDLE;
2111 return -EINVAL;
2112 }
2113
2114 if (frm->ulState == S2255_READ_IDLE) {
2115 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002116 frm->cur_size = 0;
2117 }
2118
Dean Anderson14d96262008-08-25 13:58:55 -03002119 /* skip the marker 512 bytes (and offset if out of sync) */
2120 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2121
Dean Anderson38f993a2008-06-26 23:15:51 -03002122
2123 if (frm->lpvbits == NULL) {
2124 dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
2125 frm, dev, dev->cc, idx);
2126 return -ENOMEM;
2127 }
2128
2129 pdest = frm->lpvbits + frm->cur_size;
2130
Dean Anderson14d96262008-08-25 13:58:55 -03002131 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002132
Dean Andersonfe85ce92010-06-01 19:12:07 -03002133 size = channel->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002134
Dean Anderson14d96262008-08-25 13:58:55 -03002135 /* sanity check on pdest */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002136 if ((copy_size + frm->cur_size) < channel->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03002137 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002138
Dean Anderson38f993a2008-06-26 23:15:51 -03002139 frm->cur_size += copy_size;
Dean Anderson14d96262008-08-25 13:58:55 -03002140 dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002141
Dean Anderson14d96262008-08-25 13:58:55 -03002142 if (frm->cur_size >= size) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002143 dprintk(2, "****************[%d]Buffer[%d]full*************\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002144 dev->cc, idx);
2145 channel->last_frame = channel->cur_frame;
2146 channel->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002147 /* end of system frame ring buffer, start at zero */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002148 if ((channel->cur_frame == SYS_FRAMES) ||
2149 (channel->cur_frame == channel->buffer.dwFrames))
2150 channel->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002151 /* frame ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002152 if (channel->b_acquire)
2153 s2255_got_frame(channel, channel->jpg_size);
2154 channel->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03002155 frm->ulState = S2255_READ_IDLE;
2156 frm->cur_size = 0;
2157
Dean Anderson38f993a2008-06-26 23:15:51 -03002158 }
2159 /* done successfully */
2160 return 0;
2161}
2162
2163static void s2255_read_video_callback(struct s2255_dev *dev,
2164 struct s2255_pipeinfo *pipe_info)
2165{
2166 int res;
2167 dprintk(50, "callback read video \n");
2168
2169 if (dev->cc >= MAX_CHANNELS) {
2170 dev->cc = 0;
2171 dev_err(&dev->udev->dev, "invalid channel\n");
2172 return;
2173 }
2174 /* otherwise copy to the system buffers */
2175 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002176 if (res != 0)
2177 dprintk(4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002178
2179 dprintk(50, "callback read video done\n");
2180 return;
2181}
2182
2183static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2184 u16 Index, u16 Value, void *TransferBuffer,
2185 s32 TransferBufferLength, int bOut)
2186{
2187 int r;
2188 if (!bOut) {
2189 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2190 Request,
2191 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2192 USB_DIR_IN,
2193 Value, Index, TransferBuffer,
2194 TransferBufferLength, HZ * 5);
2195 } else {
2196 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2197 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2198 Value, Index, TransferBuffer,
2199 TransferBufferLength, HZ * 5);
2200 }
2201 return r;
2202}
2203
2204/*
2205 * retrieve FX2 firmware version. future use.
2206 * @param dev pointer to device extension
2207 * @return -1 for fail, else returns firmware version as an int(16 bits)
2208 */
2209static int s2255_get_fx2fw(struct s2255_dev *dev)
2210{
2211 int fw;
2212 int ret;
2213 unsigned char transBuffer[64];
2214 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2215 S2255_VR_IN);
2216 if (ret < 0)
2217 dprintk(2, "get fw error: %x\n", ret);
2218 fw = transBuffer[0] + (transBuffer[1] << 8);
2219 dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
2220 return fw;
2221}
2222
2223/*
2224 * Create the system ring buffer to copy frames into from the
2225 * usb read pipe.
2226 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002227static int s2255_create_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002228{
2229 unsigned long i;
2230 unsigned long reqsize;
2231 dprintk(1, "create sys buffers\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002232 channel->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03002233 /* always allocate maximum size(PAL) for system buffers */
2234 reqsize = SYS_FRAMES_MAXSIZE;
2235
2236 if (reqsize > SYS_FRAMES_MAXSIZE)
2237 reqsize = SYS_FRAMES_MAXSIZE;
2238
2239 for (i = 0; i < SYS_FRAMES; i++) {
2240 /* allocate the frames */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002241 channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
2242 dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
2243 &channel->buffer.frame[i], channel->idx, i,
2244 channel->buffer.frame[i].lpvbits);
2245 channel->buffer.frame[i].size = reqsize;
2246 if (channel->buffer.frame[i].lpvbits == NULL) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002247 printk(KERN_INFO "out of memory. using less frames\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002248 channel->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002249 break;
2250 }
2251 }
2252
2253 /* make sure internal states are set */
2254 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002255 channel->buffer.frame[i].ulState = 0;
2256 channel->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002257 }
2258
Dean Andersonfe85ce92010-06-01 19:12:07 -03002259 channel->cur_frame = 0;
2260 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002261 return 0;
2262}
2263
Dean Andersonfe85ce92010-06-01 19:12:07 -03002264static int s2255_release_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002265{
2266 unsigned long i;
2267 dprintk(1, "release sys buffers\n");
2268 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002269 if (channel->buffer.frame[i].lpvbits) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002270 dprintk(1, "vfree %p\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002271 channel->buffer.frame[i].lpvbits);
2272 vfree(channel->buffer.frame[i].lpvbits);
Dean Anderson38f993a2008-06-26 23:15:51 -03002273 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002274 channel->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002275 }
2276 return 0;
2277}
2278
2279static int s2255_board_init(struct s2255_dev *dev)
2280{
Dean Anderson38f993a2008-06-26 23:15:51 -03002281 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2282 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002283 int j;
2284 struct s2255_pipeinfo *pipe = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002285 dprintk(4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002286 memset(pipe, 0, sizeof(*pipe));
2287 pipe->dev = dev;
2288 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2289 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002290
Dean Andersonab85c6a2010-04-08 23:39:12 -03002291 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2292 GFP_KERNEL);
2293 if (pipe->transfer_buffer == NULL) {
2294 dprintk(1, "out of memory!\n");
2295 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002296 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002297 /* query the firmware */
2298 fw_ver = s2255_get_fx2fw(dev);
2299
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -03002300 printk(KERN_INFO "s2255: usb firmware version %d.%d\n",
Dean Andersonabce21f2009-04-23 16:04:41 -03002301 (fw_ver >> 8) & 0xff,
2302 fw_ver & 0xff);
2303
2304 if (fw_ver < S2255_CUR_USB_FWVER)
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -03002305 printk(KERN_INFO "s2255: newer USB firmware available\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002306
2307 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002308 struct s2255_channel *channel = &dev->channel[j];
2309 channel->b_acquire = 0;
2310 channel->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002311 if (dev->pid == 0x2257 && j > 1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002312 channel->mode.color |= (1 << 16);
2313 channel->jc.quality = S2255_DEF_JPEG_QUAL;
2314 channel->width = LINE_SZ_4CIFS_NTSC;
2315 channel->height = NUM_LINES_4CIFS_NTSC * 2;
2316 channel->fmt = &formats[0];
2317 channel->mode.restart = 1;
2318 channel->req_image_size = get_transfer_size(&mode_def);
2319 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002320 /* create the system buffers */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002321 s2255_create_sys_buffers(channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03002322 }
2323 /* start read pipe */
2324 s2255_start_readpipe(dev);
Dean Anderson85b85482010-04-08 23:51:17 -03002325 dprintk(1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002326 return 0;
2327}
2328
2329static int s2255_board_shutdown(struct s2255_dev *dev)
2330{
2331 u32 i;
Dean Anderson85b85482010-04-08 23:51:17 -03002332 dprintk(1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002333
2334 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002335 if (dev->channel[i].b_acquire)
2336 s2255_stop_acquire(&dev->channel[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002337 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002338 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002339 for (i = 0; i < MAX_CHANNELS; i++)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002340 s2255_release_sys_buffers(&dev->channel[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002341 /* release transfer buffer */
2342 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002343 return 0;
2344}
2345
2346static void read_pipe_completion(struct urb *purb)
2347{
2348 struct s2255_pipeinfo *pipe_info;
2349 struct s2255_dev *dev;
2350 int status;
2351 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002352 pipe_info = purb->context;
Dean Anderson85b85482010-04-08 23:51:17 -03002353 dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
Dean Anderson38f993a2008-06-26 23:15:51 -03002354 purb->status);
2355 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002356 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002357 return;
2358 }
2359
2360 dev = pipe_info->dev;
2361 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002362 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002363 return;
2364 }
2365 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002366 /* if shutting down, do not resubmit, exit immediately */
2367 if (status == -ESHUTDOWN) {
Dean Anderson85b85482010-04-08 23:51:17 -03002368 dprintk(2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002369 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002370 return;
2371 }
2372
2373 if (pipe_info->state == 0) {
Dean Anderson85b85482010-04-08 23:51:17 -03002374 dprintk(2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002375 return;
2376 }
2377
Dean Andersonb02064c2009-04-30 12:29:38 -03002378 if (status == 0)
2379 s2255_read_video_callback(dev, pipe_info);
2380 else {
2381 pipe_info->err_count++;
Dean Anderson85b85482010-04-08 23:51:17 -03002382 dprintk(1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002383 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002384
Dean Anderson38f993a2008-06-26 23:15:51 -03002385 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2386 /* reuse urb */
2387 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2388 pipe,
2389 pipe_info->transfer_buffer,
2390 pipe_info->cur_transfer_size,
2391 read_pipe_completion, pipe_info);
2392
2393 if (pipe_info->state != 0) {
Pete Eberleina1b4c862011-04-01 21:21:26 -03002394 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002395 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002396 }
2397 } else {
Dean Anderson85b85482010-04-08 23:51:17 -03002398 dprintk(2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002399 }
2400 return;
2401}
2402
2403static int s2255_start_readpipe(struct s2255_dev *dev)
2404{
2405 int pipe;
2406 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002407 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002408 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
Dean Anderson85b85482010-04-08 23:51:17 -03002409 dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002410 pipe_info->state = 1;
2411 pipe_info->err_count = 0;
2412 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2413 if (!pipe_info->stream_urb) {
2414 dev_err(&dev->udev->dev,
2415 "ReadStream: Unable to alloc URB\n");
2416 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002417 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002418 /* transfer buffer allocated in board_init */
2419 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2420 pipe,
2421 pipe_info->transfer_buffer,
2422 pipe_info->cur_transfer_size,
2423 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002424 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2425 if (retval) {
2426 printk(KERN_ERR "s2255: start read pipe failed\n");
2427 return retval;
2428 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002429 return 0;
2430}
2431
2432/* starts acquisition process */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002433static int s2255_start_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002434{
2435 unsigned char *buffer;
2436 int res;
2437 unsigned long chn_rev;
2438 int j;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002439 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2440 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002441 buffer = kzalloc(512, GFP_KERNEL);
2442 if (buffer == NULL) {
2443 dev_err(&dev->udev->dev, "out of mem\n");
2444 return -ENOMEM;
2445 }
2446
Dean Andersonfe85ce92010-06-01 19:12:07 -03002447 channel->last_frame = -1;
2448 channel->bad_payload = 0;
2449 channel->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002450 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002451 channel->buffer.frame[j].ulState = 0;
2452 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002453 }
2454
2455 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002456 *(__le32 *) buffer = IN_DATA_TOKEN;
2457 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2458 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002459 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2460 if (res != 0)
2461 dev_err(&dev->udev->dev, "CMD_START error\n");
2462
Dean Andersonfe85ce92010-06-01 19:12:07 -03002463 dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03002464 kfree(buffer);
2465 return 0;
2466}
2467
Dean Andersonfe85ce92010-06-01 19:12:07 -03002468static int s2255_stop_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002469{
2470 unsigned char *buffer;
2471 int res;
2472 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002473 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2474 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002475 buffer = kzalloc(512, GFP_KERNEL);
2476 if (buffer == NULL) {
2477 dev_err(&dev->udev->dev, "out of mem\n");
2478 return -ENOMEM;
2479 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002480 /* send the stop command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002481 *(__le32 *) buffer = IN_DATA_TOKEN;
2482 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2483 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002484 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002485 if (res != 0)
2486 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002487 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002488 channel->b_acquire = 0;
2489 dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
Dean Anderson14d96262008-08-25 13:58:55 -03002490 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002491}
2492
2493static void s2255_stop_readpipe(struct s2255_dev *dev)
2494{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002495 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002496
Dean Andersonab85c6a2010-04-08 23:39:12 -03002497 pipe->state = 0;
2498 if (pipe->stream_urb) {
2499 /* cancel urb */
2500 usb_kill_urb(pipe->stream_urb);
2501 usb_free_urb(pipe->stream_urb);
2502 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002503 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002504 dprintk(4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002505 return;
2506}
2507
Dean Anderson14d96262008-08-25 13:58:55 -03002508static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002509{
Dean Anderson14d96262008-08-25 13:58:55 -03002510 if (reset)
2511 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002512 dev->fw_data->fw_size = dev->fw_data->fw->size;
2513 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2514 memcpy(dev->fw_data->pfw_data,
2515 dev->fw_data->fw->data, CHUNK_SIZE);
2516 dev->fw_data->fw_loaded = CHUNK_SIZE;
2517 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2518 usb_sndbulkpipe(dev->udev, 2),
2519 dev->fw_data->pfw_data,
2520 CHUNK_SIZE, s2255_fwchunk_complete,
2521 dev->fw_data);
2522 mod_timer(&dev->timer, jiffies + HZ);
2523}
2524
2525/* standard usb probe function */
2526static int s2255_probe(struct usb_interface *interface,
2527 const struct usb_device_id *id)
2528{
2529 struct s2255_dev *dev = NULL;
2530 struct usb_host_interface *iface_desc;
2531 struct usb_endpoint_descriptor *endpoint;
2532 int i;
2533 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002534 __le32 *pdata;
2535 int fw_size;
Dean Anderson85b85482010-04-08 23:51:17 -03002536 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002537 /* allocate memory for our device state and initialize it to zero */
2538 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2539 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002540 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002541 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002542 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002543 atomic_set(&dev->num_channels, 0);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002544 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002545 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2546 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002547 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002548 mutex_init(&dev->lock);
2549 mutex_init(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002550 /* grab usb_device and save it */
2551 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2552 if (dev->udev == NULL) {
2553 dev_err(&interface->dev, "null usb device\n");
2554 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002555 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002556 }
Dean Andersond62e85a2010-04-09 19:54:26 -03002557 dprintk(1, "dev: %p, udev %p interface %p\n", dev,
Dean Anderson38f993a2008-06-26 23:15:51 -03002558 dev->udev, interface);
2559 dev->interface = interface;
2560 /* set up the endpoint information */
2561 iface_desc = interface->cur_altsetting;
2562 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2563 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2564 endpoint = &iface_desc->endpoint[i].desc;
2565 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2566 /* we found the bulk in endpoint */
2567 dev->read_endpoint = endpoint->bEndpointAddress;
2568 }
2569 }
2570
2571 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002572 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002573 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002574 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002575 init_timer(&dev->timer);
2576 dev->timer.function = s2255_timer;
2577 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002578 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002579 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002580 struct s2255_channel *channel = &dev->channel[i];
2581 dev->channel[i].idx = i;
2582 init_waitqueue_head(&channel->wait_setmode);
2583 init_waitqueue_head(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002584 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002585
2586 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002587 if (!dev->fw_data->fw_urb) {
2588 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002589 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002590 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002591
Dean Anderson38f993a2008-06-26 23:15:51 -03002592 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2593 if (!dev->fw_data->pfw_data) {
2594 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002595 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002596 }
2597 /* load the first chunk */
2598 if (request_firmware(&dev->fw_data->fw,
2599 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2600 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002601 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002602 }
Dean Anderson14d96262008-08-25 13:58:55 -03002603 /* check the firmware is valid */
2604 fw_size = dev->fw_data->fw->size;
2605 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002606
Dean Anderson14d96262008-08-25 13:58:55 -03002607 if (*pdata != S2255_FW_MARKER) {
2608 printk(KERN_INFO "Firmware invalid.\n");
2609 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002610 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002611 } else {
2612 /* make sure firmware is the latest */
2613 __le32 *pRel;
2614 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2615 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dean Anderson4de39f52010-03-03 19:39:19 -03002616 dev->dsp_fw_ver = *pRel;
2617 if (*pRel < S2255_CUR_DSP_FWVER)
2618 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002619 if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002620 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
Dean Andersonfe85ce92010-06-01 19:12:07 -03002621 " or above.\n", S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002622 }
Dean Anderson14d96262008-08-25 13:58:55 -03002623 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002624 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002625 retval = s2255_board_init(dev);
2626 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002627 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002628 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002629 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002630 /* loads v4l specific */
2631 retval = s2255_probe_v4l(dev);
2632 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002633 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002634 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2635 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002636errorBOARDINIT:
2637 s2255_board_shutdown(dev);
2638errorFWMARKER:
2639 release_firmware(dev->fw_data->fw);
2640errorREQFW:
2641 kfree(dev->fw_data->pfw_data);
2642errorFWDATA2:
2643 usb_free_urb(dev->fw_data->fw_urb);
2644errorFWURB:
2645 del_timer(&dev->timer);
2646errorEP:
2647 usb_put_dev(dev->udev);
2648errorUDEV:
2649 kfree(dev->fw_data);
2650 mutex_destroy(&dev->open_lock);
2651 mutex_destroy(&dev->lock);
2652errorFWDATA1:
2653 kfree(dev);
2654 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002655 return retval;
2656}
2657
2658/* disconnect routine. when board is removed physically or with rmmod */
2659static void s2255_disconnect(struct usb_interface *interface)
2660{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002661 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002662 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002663 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002664 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002665 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002666 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002667 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002668 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002669 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002670 for (i = 0; i < channels; i++)
2671 video_unregister_device(&dev->channel[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002672 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002673 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2674 wake_up(&dev->fw_data->wait_fw);
2675 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002676 dev->channel[i].setmode_ready = 1;
2677 wake_up(&dev->channel[i].wait_setmode);
2678 dev->channel[i].vidstatus_ready = 1;
2679 wake_up(&dev->channel[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002680 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002681 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002682 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002683 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002684}
2685
2686static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002687 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002688 .probe = s2255_probe,
2689 .disconnect = s2255_disconnect,
2690 .id_table = s2255_table,
2691};
2692
2693static int __init usb_s2255_init(void)
2694{
2695 int result;
Dean Anderson38f993a2008-06-26 23:15:51 -03002696 /* register this driver with the USB subsystem */
2697 result = usb_register(&s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002698 if (result)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002699 pr_err(KBUILD_MODNAME
Dean Andersonff7e22d2010-04-08 23:38:07 -03002700 ": usb_register failed. Error number %d\n", result);
2701 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002702 return result;
2703}
2704
2705static void __exit usb_s2255_exit(void)
2706{
2707 usb_deregister(&s2255_driver);
2708}
2709
2710module_init(usb_s2255_init);
2711module_exit(usb_s2255_exit);
2712
2713MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2714MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2715MODULE_LICENSE("GPL");