blob: 2191f6ddf9e7536883a6b7e7973ceeba30b0ef61 [file] [log] [blame]
Dean Anderson38f993a2008-06-26 23:15:51 -03001/*
2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
3 *
Dean Anderson4de39f52010-03-03 19:39:19 -03004 * Copyright (C) 2007-2010 by Sensoray Company Inc.
Dean Anderson38f993a2008-06-26 23:15:51 -03005 * Dean Anderson
6 *
7 * Some video buffer code based on vivi driver:
8 *
9 * Sensoray 2255 device supports 4 simultaneous channels.
10 * The channels are not "crossbar" inputs, they are physically
11 * attached to separate video decoders.
12 *
13 * Because of USB2.0 bandwidth limitations. There is only a
14 * certain amount of data which may be transferred at one time.
15 *
16 * Example maximum bandwidth utilization:
17 *
18 * -full size, color mode YUYV or YUV422P: 2 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030019 * -full or half size Grey scale: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030020 * -half size, color mode YUYV or YUV422P: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030021 * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
22 * at once.
Dean Anderson38f993a2008-06-26 23:15:51 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * (at your option) any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 */
38
39#include <linux/module.h>
40#include <linux/firmware.h>
41#include <linux/kernel.h>
42#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090043#include <linux/slab.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030044#include <linux/videodev2.h>
Hans Verkuilfeb75f02008-07-27 06:30:21 -030045#include <linux/mm.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030046#include <media/videobuf-vmalloc.h>
47#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030048#include <media/v4l2-device.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030049#include <media/v4l2-ioctl.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030050#include <linux/vmalloc.h>
51#include <linux/usb.h>
52
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -030053#define S2255_VERSION "1.22.1"
Dean Anderson38f993a2008-06-26 23:15:51 -030054#define FIRMWARE_FILE_NAME "f2255usb.bin"
55
Dean Anderson22b88d42008-08-29 15:33:19 -030056/* default JPEG quality */
57#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030058/* vendor request in */
59#define S2255_VR_IN 0
60/* vendor request out */
61#define S2255_VR_OUT 1
62/* firmware query */
63#define S2255_VR_FW 0x30
64/* USB endpoint number for configuring the device */
65#define S2255_CONFIG_EP 2
66/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030067#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030068/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030069#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson38f993a2008-06-26 23:15:51 -030070#define S2255_DEF_BUFS 16
Dean Anderson14d96262008-08-25 13:58:55 -030071#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030072#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030073#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
74#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
75#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
76#define S2255_RESPONSE_FW cpu_to_le32(0x10)
77#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030078#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030079#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030080#define SYS_FRAMES 4
81/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030082#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
83#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030084#define LINE_SZ_4CIFS_NTSC 640
85#define LINE_SZ_2CIFS_NTSC 640
86#define LINE_SZ_1CIFS_NTSC 320
87#define LINE_SZ_4CIFS_PAL 704
88#define LINE_SZ_2CIFS_PAL 704
89#define LINE_SZ_1CIFS_PAL 352
90#define NUM_LINES_4CIFS_NTSC 240
91#define NUM_LINES_2CIFS_NTSC 240
92#define NUM_LINES_1CIFS_NTSC 240
93#define NUM_LINES_4CIFS_PAL 288
94#define NUM_LINES_2CIFS_PAL 288
95#define NUM_LINES_1CIFS_PAL 288
96#define LINE_SZ_DEF 640
97#define NUM_LINES_DEF 240
98
99
100/* predefined settings */
101#define FORMAT_NTSC 1
102#define FORMAT_PAL 2
103
104#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
105#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
106#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300107/* SCALE_4CIFSI is the 2 fields interpolated into one */
108#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300109
110#define COLOR_YUVPL 1 /* YUV planar */
111#define COLOR_YUVPK 2 /* YUV packed */
112#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300113#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300114
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300115#define MASK_COLOR 0x000000ff
116#define MASK_JPG_QUALITY 0x0000ff00
117#define MASK_INPUT_TYPE 0x000f0000
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300118/* frame decimation. */
Dean Anderson38f993a2008-06-26 23:15:51 -0300119#define FDEC_1 1 /* capture every frame. default */
120#define FDEC_2 2 /* capture every 2nd frame */
121#define FDEC_3 3 /* capture every 3rd frame */
122#define FDEC_5 5 /* capture every 5th frame */
123
124/*-------------------------------------------------------
125 * Default mode parameters.
126 *-------------------------------------------------------*/
127#define DEF_SCALE SCALE_4CIFS
128#define DEF_COLOR COLOR_YUVPL
129#define DEF_FDEC FDEC_1
130#define DEF_BRIGHT 0
131#define DEF_CONTRAST 0x5c
132#define DEF_SATURATION 0x80
133#define DEF_HUE 0
134
135/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300136#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
Dan Carpenter3b2a6302012-02-17 02:44:10 -0300137#define CMD_2255 0xc2255000
Dean Anderson3fa00602010-03-04 20:47:33 -0300138#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
139#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
140#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
141#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300142
143struct s2255_mode {
144 u32 format; /* input video format (NTSC, PAL) */
145 u32 scale; /* output video scale */
146 u32 color; /* output video color format */
147 u32 fdec; /* frame decimation */
148 u32 bright; /* brightness */
149 u32 contrast; /* contrast */
150 u32 saturation; /* saturation */
151 u32 hue; /* hue (NTSC only)*/
152 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
153 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
154 u32 restart; /* if DSP requires restart */
155};
156
Dean Anderson14d96262008-08-25 13:58:55 -0300157
158#define S2255_READ_IDLE 0
159#define S2255_READ_FRAME 1
160
Dean Anderson38f993a2008-06-26 23:15:51 -0300161/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300162struct s2255_framei {
163 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300164 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300165 void *lpvbits; /* image data */
166 unsigned long cur_size; /* current data copied to it */
167};
168
169/* image buffer structure */
170struct s2255_bufferi {
171 unsigned long dwFrames; /* number of frames in buffer */
172 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
173};
174
175#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
176 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300177 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300178
179struct s2255_dmaqueue {
180 struct list_head active;
Dean Anderson38f993a2008-06-26 23:15:51 -0300181 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300182};
183
184/* for firmware loading, fw_state */
185#define S2255_FW_NOTLOADED 0
186#define S2255_FW_LOADED_DSPWAIT 1
187#define S2255_FW_SUCCESS 2
188#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300189#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300190#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300191/* 2255 read states */
192#define S2255_READ_IDLE 0
193#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300194struct s2255_fw {
195 int fw_loaded;
196 int fw_size;
197 struct urb *fw_urb;
198 atomic_t fw_state;
199 void *pfw_data;
200 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300201 const struct firmware *fw;
202};
203
204struct s2255_pipeinfo {
205 u32 max_transfer_size;
206 u32 cur_transfer_size;
207 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300208 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300209 void *stream_urb;
210 void *dev; /* back pointer to s2255_dev struct*/
211 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300212 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300213};
214
215struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300216struct s2255_dev;
217
218struct s2255_channel {
219 struct video_device vdev;
220 int resources;
221 struct s2255_dmaqueue vidq;
222 struct s2255_bufferi buffer;
223 struct s2255_mode mode;
224 /* jpeg compression */
225 struct v4l2_jpegcompression jc;
226 /* capture parameters (for high quality mode full size) */
227 struct v4l2_captureparm cap_parm;
228 int cur_frame;
229 int last_frame;
230
231 int b_acquire;
232 /* allocated image size */
233 unsigned long req_image_size;
234 /* received packet size */
235 unsigned long pkt_size;
236 int bad_payload;
237 unsigned long frame_count;
238 /* if JPEG image */
239 int jpg_size;
240 /* if channel configured to default state */
241 int configured;
242 wait_queue_head_t wait_setmode;
243 int setmode_ready;
244 /* video status items */
245 int vidstatus;
246 wait_queue_head_t wait_vidstatus;
247 int vidstatus_ready;
248 unsigned int width;
249 unsigned int height;
250 const struct s2255_fmt *fmt;
251 int idx; /* channel number on device, 0-3 */
252};
253
Dean Anderson38f993a2008-06-26 23:15:51 -0300254
255struct s2255_dev {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300256 struct s2255_channel channel[MAX_CHANNELS];
Dean Anderson65c6edb2010-04-20 17:21:32 -0300257 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300258 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300259 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300260 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson38f993a2008-06-26 23:15:51 -0300261 struct usb_device *udev;
262 struct usb_interface *interface;
263 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300264 struct timer_list timer;
265 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300266 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300267 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300268 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300269 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300270 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300271 /* dsp firmware version (f2255usb.bin) */
272 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300273 u16 pid; /* product id */
Dean Anderson38f993a2008-06-26 23:15:51 -0300274};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300275
Dean Anderson65c6edb2010-04-20 17:21:32 -0300276static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
277{
278 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
279}
Dean Anderson38f993a2008-06-26 23:15:51 -0300280
281struct s2255_fmt {
282 char *name;
283 u32 fourcc;
284 int depth;
285};
286
287/* buffer for one video frame */
288struct s2255_buffer {
289 /* common v4l buffer stuff -- must be first */
290 struct videobuf_buffer vb;
291 const struct s2255_fmt *fmt;
292};
293
294struct s2255_fh {
295 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300296 struct videobuf_queue vb_vidq;
297 enum v4l2_buf_type type;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300298 struct s2255_channel *channel;
299 int resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300300};
301
Dean Andersonabce21f2009-04-23 16:04:41 -0300302/* current cypress EEPROM firmware version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300303#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
Dean Anderson4de39f52010-03-03 19:39:19 -0300304/* current DSP FW version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300305#define S2255_CUR_DSP_FWVER 10104
Dean Anderson4de39f52010-03-03 19:39:19 -0300306/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300307#define S2255_MIN_DSP_STATUS 5
308#define S2255_MIN_DSP_COLORFILTER 8
Dean Anderson38f993a2008-06-26 23:15:51 -0300309#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300310
311/* private V4L2 controls */
312
313/*
314 * The following chart displays how COLORFILTER should be set
315 * =========================================================
316 * = fourcc = COLORFILTER =
317 * = ===============================
318 * = = 0 = 1 =
319 * =========================================================
320 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
321 * = = s-video or = composite =
322 * = = B/W camera = input =
323 * =========================================================
324 * = other = color, svideo = color, =
325 * = = = composite =
326 * =========================================================
327 *
328 * Notes:
329 * channels 0-3 on 2255 are composite
330 * channels 0-1 on 2257 are composite, 2-3 are s-video
331 * If COLORFILTER is 0 with a composite color camera connected,
332 * the output will appear monochrome but hatching
333 * will occur.
334 * COLORFILTER is different from "color killer" and "color effects"
335 * for reasons above.
336 */
337#define S2255_V4L2_YC_ON 1
338#define S2255_V4L2_YC_OFF 0
339#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
340
Dean Anderson38f993a2008-06-26 23:15:51 -0300341/* frame prefix size (sent once every frame) */
342#define PREFIX_SIZE 512
343
344/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300345static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300346
Dean Anderson38f993a2008-06-26 23:15:51 -0300347static int debug;
348static int *s2255_debug = &debug;
349
350static int s2255_start_readpipe(struct s2255_dev *dev);
351static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300352static int s2255_start_acquire(struct s2255_channel *channel);
353static int s2255_stop_acquire(struct s2255_channel *channel);
354static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
355 int jpgsize);
356static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300357static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300358static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300359static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300360static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
361 u16 index, u16 value, void *buf,
362 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300363
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300364/* dev_err macro with driver name */
365#define S2255_DRIVER_NAME "s2255"
366#define s2255_dev_err(dev, fmt, arg...) \
367 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
368
Dean Anderson38f993a2008-06-26 23:15:51 -0300369#define dprintk(level, fmt, arg...) \
370 do { \
371 if (*s2255_debug >= (level)) { \
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300372 printk(KERN_DEBUG S2255_DRIVER_NAME \
373 ": " fmt, ##arg); \
Dean Anderson38f993a2008-06-26 23:15:51 -0300374 } \
375 } while (0)
376
Dean Anderson38f993a2008-06-26 23:15:51 -0300377static struct usb_driver s2255_driver;
378
Dean Anderson38f993a2008-06-26 23:15:51 -0300379/* Declare static vars that will be used as parameters */
380static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
381
382/* start video number */
383static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
384
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300385/* Enable jpeg capture. */
386static int jpeg_enable = 1;
387
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300388module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300389MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300390module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300391MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300392module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300393MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300394module_param(jpeg_enable, int, 0644);
395MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
Dean Anderson38f993a2008-06-26 23:15:51 -0300396
397/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300398#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300399static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300400 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
401 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300402 { } /* Terminating entry */
403};
404MODULE_DEVICE_TABLE(usb, s2255_table);
405
Dean Anderson38f993a2008-06-26 23:15:51 -0300406#define BUFFER_TIMEOUT msecs_to_jiffies(400)
407
Dean Anderson38f993a2008-06-26 23:15:51 -0300408/* image formats. */
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300409/* JPEG formats must be defined last to support jpeg_enable parameter */
Dean Anderson38f993a2008-06-26 23:15:51 -0300410static const struct s2255_fmt formats[] = {
411 {
412 .name = "4:2:2, planar, YUV422P",
413 .fourcc = V4L2_PIX_FMT_YUV422P,
414 .depth = 16
415
416 }, {
417 .name = "4:2:2, packed, YUYV",
418 .fourcc = V4L2_PIX_FMT_YUYV,
419 .depth = 16
420
421 }, {
422 .name = "4:2:2, packed, UYVY",
423 .fourcc = V4L2_PIX_FMT_UYVY,
424 .depth = 16
425 }, {
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300426 .name = "8bpp GREY",
427 .fourcc = V4L2_PIX_FMT_GREY,
428 .depth = 8
429 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300430 .name = "JPG",
431 .fourcc = V4L2_PIX_FMT_JPEG,
432 .depth = 24
433 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300434 .name = "MJPG",
435 .fourcc = V4L2_PIX_FMT_MJPEG,
436 .depth = 24
Dean Anderson38f993a2008-06-26 23:15:51 -0300437 }
438};
439
440static int norm_maxw(struct video_device *vdev)
441{
442 return (vdev->current_norm & V4L2_STD_NTSC) ?
443 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
444}
445
446static int norm_maxh(struct video_device *vdev)
447{
448 return (vdev->current_norm & V4L2_STD_NTSC) ?
449 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
450}
451
452static int norm_minw(struct video_device *vdev)
453{
454 return (vdev->current_norm & V4L2_STD_NTSC) ?
455 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
456}
457
458static int norm_minh(struct video_device *vdev)
459{
460 return (vdev->current_norm & V4L2_STD_NTSC) ?
461 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
462}
463
464
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300465/*
466 * TODO: fixme: move YUV reordering to hardware
467 * converts 2255 planar format to yuyv or uyvy
468 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300469static void planar422p_to_yuv_packed(const unsigned char *in,
470 unsigned char *out,
471 int width, int height,
472 int fmt)
473{
474 unsigned char *pY;
475 unsigned char *pCb;
476 unsigned char *pCr;
477 unsigned long size = height * width;
478 unsigned int i;
479 pY = (unsigned char *)in;
480 pCr = (unsigned char *)in + height * width;
481 pCb = (unsigned char *)in + height * width + (height * width / 2);
482 for (i = 0; i < size * 2; i += 4) {
483 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
484 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
485 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
486 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
487 }
488 return;
489}
490
Hans Verkuild45b9b82008-09-04 03:33:43 -0300491static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300492{
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300493 s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300494 msleep(10);
495 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300496 msleep(600);
497 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300498 return;
499}
Dean Anderson38f993a2008-06-26 23:15:51 -0300500
501/* kickstarts the firmware loading. from probe
502 */
503static void s2255_timer(unsigned long user_data)
504{
505 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson85b85482010-04-08 23:51:17 -0300506 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300507 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
508 printk(KERN_ERR "s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300509 atomic_set(&data->fw_state, S2255_FW_FAILED);
510 /* wake up anything waiting for the firmware */
511 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300512 return;
513 }
514}
515
Dean Anderson38f993a2008-06-26 23:15:51 -0300516
517/* this loads the firmware asynchronously.
518 Originally this was done synchroously in probe.
519 But it is better to load it asynchronously here than block
520 inside the probe function. Blocking inside probe affects boot time.
521 FW loading is triggered by the timer in the probe function
522*/
523static void s2255_fwchunk_complete(struct urb *urb)
524{
525 struct s2255_fw *data = urb->context;
526 struct usb_device *udev = urb->dev;
527 int len;
Dean Anderson85b85482010-04-08 23:51:17 -0300528 dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
Dean Anderson38f993a2008-06-26 23:15:51 -0300529 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300530 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300531 atomic_set(&data->fw_state, S2255_FW_FAILED);
532 /* wake up anything waiting for the firmware */
533 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300534 return;
535 }
536 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300537 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300538 atomic_set(&data->fw_state, S2255_FW_FAILED);
539 /* wake up anything waiting for the firmware */
540 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300541 return;
542 }
543#define CHUNK_SIZE 512
544 /* all USB transfers must be done with continuous kernel memory.
545 can't allocate more than 128k in current linux kernel, so
546 upload the firmware in chunks
547 */
548 if (data->fw_loaded < data->fw_size) {
549 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
550 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
551
552 if (len < CHUNK_SIZE)
553 memset(data->pfw_data, 0, CHUNK_SIZE);
554
555 dprintk(100, "completed len %d, loaded %d \n", len,
556 data->fw_loaded);
557
558 memcpy(data->pfw_data,
559 (char *) data->fw->data + data->fw_loaded, len);
560
561 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
562 data->pfw_data, CHUNK_SIZE,
563 s2255_fwchunk_complete, data);
564 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
565 dev_err(&udev->dev, "failed submit URB\n");
566 atomic_set(&data->fw_state, S2255_FW_FAILED);
567 /* wake up anything waiting for the firmware */
568 wake_up(&data->wait_fw);
569 return;
570 }
571 data->fw_loaded += len;
572 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300573 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson85b85482010-04-08 23:51:17 -0300574 dprintk(100, "%s: firmware upload complete\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300575 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300576 return;
577
578}
579
Dean Andersonfe85ce92010-06-01 19:12:07 -0300580static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300581{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300582 struct s2255_dmaqueue *dma_q = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300583 struct s2255_buffer *buf;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300584 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300585 unsigned long flags = 0;
586 int rc = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300587 spin_lock_irqsave(&dev->slock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300588 if (list_empty(&dma_q->active)) {
589 dprintk(1, "No active queue to serve\n");
590 rc = -1;
591 goto unlock;
592 }
593 buf = list_entry(dma_q->active.next,
594 struct s2255_buffer, vb.queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300595 list_del(&buf->vb.queue);
596 do_gettimeofday(&buf->vb.ts);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300597 s2255_fillbuff(channel, buf, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300598 wake_up(&buf->vb.done);
Dean Anderson85b85482010-04-08 23:51:17 -0300599 dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
Dean Anderson38f993a2008-06-26 23:15:51 -0300600unlock:
601 spin_unlock_irqrestore(&dev->slock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300602 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300603}
604
Dean Anderson38f993a2008-06-26 23:15:51 -0300605static const struct s2255_fmt *format_by_fourcc(int fourcc)
606{
607 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300608 for (i = 0; i < ARRAY_SIZE(formats); i++) {
609 if (-1 == formats[i].fourcc)
610 continue;
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300611 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
612 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
613 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300614 if (formats[i].fourcc == fourcc)
615 return formats + i;
616 }
617 return NULL;
618}
619
Dean Anderson38f993a2008-06-26 23:15:51 -0300620/* video buffer vmalloc implementation based partly on VIVI driver which is
621 * Copyright (c) 2006 by
622 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
623 * Ted Walther <ted--a.t--enumera.com>
624 * John Sokol <sokol--a.t--videotechnology.com>
625 * http://v4l.videotechnology.com/
626 *
627 */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300628static void s2255_fillbuff(struct s2255_channel *channel,
629 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300630{
631 int pos = 0;
632 struct timeval ts;
633 const char *tmpbuf;
634 char *vbuf = videobuf_to_vmalloc(&buf->vb);
635 unsigned long last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300636
637 if (!vbuf)
638 return;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300639 last_frame = channel->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300640 if (last_frame != -1) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300641 tmpbuf =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300642 (const char *)channel->buffer.frame[last_frame].lpvbits;
Dean Anderson38f993a2008-06-26 23:15:51 -0300643 switch (buf->fmt->fourcc) {
644 case V4L2_PIX_FMT_YUYV:
645 case V4L2_PIX_FMT_UYVY:
646 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
647 vbuf, buf->vb.width,
648 buf->vb.height,
649 buf->fmt->fourcc);
650 break;
651 case V4L2_PIX_FMT_GREY:
652 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
653 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300654 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300655 case V4L2_PIX_FMT_MJPEG:
Dean Anderson14d96262008-08-25 13:58:55 -0300656 buf->vb.size = jpgsize;
657 memcpy(vbuf, tmpbuf, buf->vb.size);
658 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300659 case V4L2_PIX_FMT_YUV422P:
660 memcpy(vbuf, tmpbuf,
661 buf->vb.width * buf->vb.height * 2);
662 break;
663 default:
664 printk(KERN_DEBUG "s2255: unknown format?\n");
665 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300666 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300667 } else {
668 printk(KERN_ERR "s2255: =======no frame\n");
669 return;
670
671 }
672 dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
673 (unsigned long)vbuf, pos);
674 /* tell v4l buffer was filled */
675
Dean Andersonfe85ce92010-06-01 19:12:07 -0300676 buf->vb.field_count = channel->frame_count * 2;
Dean Anderson38f993a2008-06-26 23:15:51 -0300677 do_gettimeofday(&ts);
678 buf->vb.ts = ts;
679 buf->vb.state = VIDEOBUF_DONE;
680}
681
682
683/* ------------------------------------------------------------------
684 Videobuf operations
685 ------------------------------------------------------------------*/
686
687static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
688 unsigned int *size)
689{
690 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300691 struct s2255_channel *channel = fh->channel;
692 *size = channel->width * channel->height * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300693
694 if (0 == *count)
695 *count = S2255_DEF_BUFS;
696
Andreas Bombedab7e312010-03-21 16:02:45 -0300697 if (*size * *count > vid_limit * 1024 * 1024)
698 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300699
700 return 0;
701}
702
703static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
704{
705 dprintk(4, "%s\n", __func__);
706
Dean Anderson38f993a2008-06-26 23:15:51 -0300707 videobuf_vmalloc_free(&buf->vb);
708 buf->vb.state = VIDEOBUF_NEEDS_INIT;
709}
710
711static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
712 enum v4l2_field field)
713{
714 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300715 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300716 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
717 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300718 int w = channel->width;
719 int h = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300720 dprintk(4, "%s, field=%d\n", __func__, field);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300721 if (channel->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300722 return -EINVAL;
723
Dean Andersonfe85ce92010-06-01 19:12:07 -0300724 if ((w < norm_minw(&channel->vdev)) ||
725 (w > norm_maxw(&channel->vdev)) ||
726 (h < norm_minh(&channel->vdev)) ||
727 (h > norm_maxh(&channel->vdev))) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300728 dprintk(4, "invalid buffer prepare\n");
729 return -EINVAL;
730 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300731 buf->vb.size = w * h * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300732 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
733 dprintk(4, "invalid buffer prepare\n");
734 return -EINVAL;
735 }
736
Dean Andersonfe85ce92010-06-01 19:12:07 -0300737 buf->fmt = channel->fmt;
738 buf->vb.width = w;
739 buf->vb.height = h;
Dean Anderson38f993a2008-06-26 23:15:51 -0300740 buf->vb.field = field;
741
Dean Anderson38f993a2008-06-26 23:15:51 -0300742 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
743 rc = videobuf_iolock(vq, &buf->vb, NULL);
744 if (rc < 0)
745 goto fail;
746 }
747
748 buf->vb.state = VIDEOBUF_PREPARED;
749 return 0;
750fail:
751 free_buffer(vq, buf);
752 return rc;
753}
754
755static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
756{
757 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
758 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300759 struct s2255_channel *channel = fh->channel;
760 struct s2255_dmaqueue *vidq = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300761 dprintk(1, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300762 buf->vb.state = VIDEOBUF_QUEUED;
763 list_add_tail(&buf->vb.queue, &vidq->active);
764}
765
766static void buffer_release(struct videobuf_queue *vq,
767 struct videobuf_buffer *vb)
768{
769 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
770 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300771 dprintk(4, "%s %d\n", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -0300772 free_buffer(vq, buf);
773}
774
775static struct videobuf_queue_ops s2255_video_qops = {
776 .buf_setup = buffer_setup,
777 .buf_prepare = buffer_prepare,
778 .buf_queue = buffer_queue,
779 .buf_release = buffer_release,
780};
781
782
Dean Andersonfe85ce92010-06-01 19:12:07 -0300783static int res_get(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300784{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300785 struct s2255_channel *channel = fh->channel;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300786 /* is it free? */
787 if (channel->resources)
788 return 0; /* no, someone else uses it */
Dean Anderson38f993a2008-06-26 23:15:51 -0300789 /* it's free, grab it */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300790 channel->resources = 1;
791 fh->resources = 1;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300792 dprintk(1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300793 return 1;
794}
795
Dean Andersonfe85ce92010-06-01 19:12:07 -0300796static int res_locked(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300797{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300798 return fh->channel->resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300799}
800
Dean Andersonf78d92c2008-07-22 14:43:27 -0300801static int res_check(struct s2255_fh *fh)
802{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300803 return fh->resources;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300804}
805
806
Dean Andersonfe85ce92010-06-01 19:12:07 -0300807static void res_free(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300808{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300809 struct s2255_channel *channel = fh->channel;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300810 channel->resources = 0;
811 fh->resources = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300812 dprintk(1, "res: put\n");
813}
814
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300815static int vidioc_querymenu(struct file *file, void *priv,
816 struct v4l2_querymenu *qmenu)
817{
818 static const char *colorfilter[] = {
819 "Off",
820 "On",
821 NULL
822 };
823 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
824 int i;
825 const char **menu_items = colorfilter;
826 for (i = 0; i < qmenu->index && menu_items[i]; i++)
827 ; /* do nothing (from v4l2-common.c) */
828 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
829 return -EINVAL;
830 strlcpy(qmenu->name, menu_items[qmenu->index],
831 sizeof(qmenu->name));
832 return 0;
833 }
834 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
835}
836
Dean Anderson38f993a2008-06-26 23:15:51 -0300837static int vidioc_querycap(struct file *file, void *priv,
838 struct v4l2_capability *cap)
839{
840 struct s2255_fh *fh = file->private_data;
841 struct s2255_dev *dev = fh->dev;
842 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
843 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300844 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Dean Anderson38f993a2008-06-26 23:15:51 -0300845 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
846 return 0;
847}
848
849static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
850 struct v4l2_fmtdesc *f)
851{
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300852 int index = f->index;
Dean Anderson38f993a2008-06-26 23:15:51 -0300853
854 if (index >= ARRAY_SIZE(formats))
855 return -EINVAL;
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300856 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
857 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
858 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300859 dprintk(4, "name %s\n", formats[index].name);
860 strlcpy(f->description, formats[index].name, sizeof(f->description));
861 f->pixelformat = formats[index].fourcc;
862 return 0;
863}
864
865static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
866 struct v4l2_format *f)
867{
868 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300869 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300870
Dean Andersonfe85ce92010-06-01 19:12:07 -0300871 f->fmt.pix.width = channel->width;
872 f->fmt.pix.height = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300873 f->fmt.pix.field = fh->vb_vidq.field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300874 f->fmt.pix.pixelformat = channel->fmt->fourcc;
875 f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300876 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300877 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300878}
879
880static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
881 struct v4l2_format *f)
882{
883 const struct s2255_fmt *fmt;
884 enum v4l2_field field;
885 int b_any_field = 0;
886 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300887 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300888 int is_ntsc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300889 is_ntsc =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300890 (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300891
892 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
893
894 if (fmt == NULL)
895 return -EINVAL;
896
897 field = f->fmt.pix.field;
898 if (field == V4L2_FIELD_ANY)
899 b_any_field = 1;
900
Dean Anderson85b85482010-04-08 23:51:17 -0300901 dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
902 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300903 if (is_ntsc) {
904 /* NTSC */
905 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
906 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
907 if (b_any_field) {
908 field = V4L2_FIELD_SEQ_TB;
909 } else if (!((field == V4L2_FIELD_INTERLACED) ||
910 (field == V4L2_FIELD_SEQ_TB) ||
911 (field == V4L2_FIELD_INTERLACED_TB))) {
912 dprintk(1, "unsupported field setting\n");
913 return -EINVAL;
914 }
915 } else {
916 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
917 if (b_any_field) {
918 field = V4L2_FIELD_TOP;
919 } else if (!((field == V4L2_FIELD_TOP) ||
920 (field == V4L2_FIELD_BOTTOM))) {
921 dprintk(1, "unsupported field setting\n");
922 return -EINVAL;
923 }
924
925 }
926 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
927 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
928 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
929 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
930 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
931 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
932 else
933 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
934 } else {
935 /* PAL */
936 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
937 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
938 if (b_any_field) {
939 field = V4L2_FIELD_SEQ_TB;
940 } else if (!((field == V4L2_FIELD_INTERLACED) ||
941 (field == V4L2_FIELD_SEQ_TB) ||
942 (field == V4L2_FIELD_INTERLACED_TB))) {
943 dprintk(1, "unsupported field setting\n");
944 return -EINVAL;
945 }
946 } else {
947 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
948 if (b_any_field) {
949 field = V4L2_FIELD_TOP;
950 } else if (!((field == V4L2_FIELD_TOP) ||
951 (field == V4L2_FIELD_BOTTOM))) {
952 dprintk(1, "unsupported field setting\n");
953 return -EINVAL;
954 }
955 }
956 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300957 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
958 field = V4L2_FIELD_SEQ_TB;
959 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300960 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
961 field = V4L2_FIELD_TOP;
962 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300963 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
964 field = V4L2_FIELD_TOP;
965 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300966 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
967 field = V4L2_FIELD_TOP;
968 }
969 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300970 f->fmt.pix.field = field;
971 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
972 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson85b85482010-04-08 23:51:17 -0300973 dprintk(50, "%s: set width %d height %d field %d\n", __func__,
974 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300975 return 0;
976}
977
978static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
979 struct v4l2_format *f)
980{
981 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300982 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300983 const struct s2255_fmt *fmt;
984 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300985 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300986 int ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300987
988 ret = vidioc_try_fmt_vid_cap(file, fh, f);
989
990 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300991 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300992
993 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
994
995 if (fmt == NULL)
996 return -EINVAL;
997
998 mutex_lock(&q->vb_lock);
999
1000 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1001 dprintk(1, "queue busy\n");
1002 ret = -EBUSY;
1003 goto out_s_fmt;
1004 }
1005
Dean Andersonfe85ce92010-06-01 19:12:07 -03001006 if (res_locked(fh)) {
Dean Anderson85b85482010-04-08 23:51:17 -03001007 dprintk(1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001008 ret = -EBUSY;
1009 goto out_s_fmt;
1010 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001011 mode = channel->mode;
1012 channel->fmt = fmt;
1013 channel->width = f->fmt.pix.width;
1014 channel->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -03001015 fh->vb_vidq.field = f->fmt.pix.field;
1016 fh->type = f->type;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001017 if (channel->width > norm_minw(&channel->vdev)) {
1018 if (channel->height > norm_minh(&channel->vdev)) {
1019 if (channel->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -03001020 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001021 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -03001022 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001023 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -03001024 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001025 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001026
1027 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001028 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001029 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001030 /* color mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001031 switch (channel->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001032 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001033 mode.color &= ~MASK_COLOR;
1034 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001035 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001036 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -03001037 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001038 mode.color &= ~MASK_COLOR;
1039 mode.color |= COLOR_JPG;
1040 mode.color |= (channel->jc.quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001041 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001042 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001043 mode.color &= ~MASK_COLOR;
1044 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001045 break;
1046 case V4L2_PIX_FMT_YUYV:
1047 case V4L2_PIX_FMT_UYVY:
1048 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001049 mode.color &= ~MASK_COLOR;
1050 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001051 break;
1052 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001053 if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
1054 mode.restart = 1;
1055 else if (mode.scale != channel->mode.scale)
1056 mode.restart = 1;
1057 else if (mode.format != channel->mode.format)
1058 mode.restart = 1;
1059 channel->mode = mode;
1060 (void) s2255_set_mode(channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001061 ret = 0;
1062out_s_fmt:
1063 mutex_unlock(&q->vb_lock);
1064 return ret;
1065}
1066
1067static int vidioc_reqbufs(struct file *file, void *priv,
1068 struct v4l2_requestbuffers *p)
1069{
1070 int rc;
1071 struct s2255_fh *fh = priv;
1072 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1073 return rc;
1074}
1075
1076static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1077{
1078 int rc;
1079 struct s2255_fh *fh = priv;
1080 rc = videobuf_querybuf(&fh->vb_vidq, p);
1081 return rc;
1082}
1083
1084static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1085{
1086 int rc;
1087 struct s2255_fh *fh = priv;
1088 rc = videobuf_qbuf(&fh->vb_vidq, p);
1089 return rc;
1090}
1091
1092static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1093{
1094 int rc;
1095 struct s2255_fh *fh = priv;
1096 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1097 return rc;
1098}
1099
Dean Anderson38f993a2008-06-26 23:15:51 -03001100/* write to the configuration pipe, synchronously */
1101static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1102 int size)
1103{
1104 int pipe;
1105 int done;
1106 long retval = -1;
1107 if (udev) {
1108 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1109 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1110 }
1111 return retval;
1112}
1113
1114static u32 get_transfer_size(struct s2255_mode *mode)
1115{
1116 int linesPerFrame = LINE_SZ_DEF;
1117 int pixelsPerLine = NUM_LINES_DEF;
1118 u32 outImageSize;
1119 u32 usbInSize;
1120 unsigned int mask_mult;
1121
1122 if (mode == NULL)
1123 return 0;
1124
1125 if (mode->format == FORMAT_NTSC) {
1126 switch (mode->scale) {
1127 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001128 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001129 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1130 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1131 break;
1132 case SCALE_2CIFS:
1133 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1134 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1135 break;
1136 case SCALE_1CIFS:
1137 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1138 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1139 break;
1140 default:
1141 break;
1142 }
1143 } else if (mode->format == FORMAT_PAL) {
1144 switch (mode->scale) {
1145 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001146 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001147 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1148 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1149 break;
1150 case SCALE_2CIFS:
1151 linesPerFrame = NUM_LINES_2CIFS_PAL;
1152 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1153 break;
1154 case SCALE_1CIFS:
1155 linesPerFrame = NUM_LINES_1CIFS_PAL;
1156 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1157 break;
1158 default:
1159 break;
1160 }
1161 }
1162 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001163 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001164 /* 2 bytes/pixel if not monochrome */
1165 outImageSize *= 2;
1166 }
1167
1168 /* total bytes to send including prefix and 4K padding;
1169 must be a multiple of USB_READ_SIZE */
1170 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1171 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1172 /* if size not a multiple of USB_READ_SIZE */
1173 if (usbInSize & ~mask_mult)
1174 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1175 return usbInSize;
1176}
1177
Dean Anderson85b85482010-04-08 23:51:17 -03001178static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001179{
1180 struct device *dev = &sdev->udev->dev;
1181 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001182 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1183 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001184 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001185 dev_info(dev, "------------------------------------------------\n");
1186}
1187
1188/*
1189 * set mode is the function which controls the DSP.
1190 * the restart parameter in struct s2255_mode should be set whenever
1191 * the image size could change via color format, video system or image
1192 * size.
1193 * When the restart parameter is set, we sleep for ONE frame to allow the
1194 * DSP time to get the new frame
1195 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001196static int s2255_set_mode(struct s2255_channel *channel,
Dean Anderson38f993a2008-06-26 23:15:51 -03001197 struct s2255_mode *mode)
1198{
1199 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001200 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001201 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001202 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001203 chn_rev = G_chnmap[channel->idx];
1204 dprintk(3, "%s channel: %d\n", __func__, channel->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001205 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001206 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1207 mode->color &= ~MASK_COLOR;
1208 mode->color |= COLOR_JPG;
1209 mode->color &= ~MASK_JPG_QUALITY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001210 mode->color |= (channel->jc.quality << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001211 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001212 /* save the mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001213 channel->mode = *mode;
1214 channel->req_image_size = get_transfer_size(mode);
1215 dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001216 buffer = kzalloc(512, GFP_KERNEL);
1217 if (buffer == NULL) {
1218 dev_err(&dev->udev->dev, "out of mem\n");
1219 return -ENOMEM;
1220 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001221 /* set the mode */
1222 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001223 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001224 buffer[2] = CMD_SET_MODE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001225 memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
1226 channel->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001227 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1228 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001229 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001230 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001231 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001232 if (mode->restart) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001233 wait_event_timeout(channel->wait_setmode,
1234 (channel->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001235 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001236 if (channel->setmode_ready != 1) {
Dean Anderson14d96262008-08-25 13:58:55 -03001237 printk(KERN_DEBUG "s2255: no set mode response\n");
1238 res = -EFAULT;
1239 }
1240 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001241 /* clear the restart flag */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001242 channel->mode.restart = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001243 dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001244 return res;
1245}
1246
Dean Andersonfe85ce92010-06-01 19:12:07 -03001247static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001248{
1249 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001250 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001251 u32 chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001252 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001253 chn_rev = G_chnmap[channel->idx];
1254 dprintk(4, "%s chan %d\n", __func__, channel->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001255 buffer = kzalloc(512, GFP_KERNEL);
1256 if (buffer == NULL) {
1257 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001258 return -ENOMEM;
1259 }
1260 /* form the get vid status command */
1261 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001262 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001263 buffer[2] = CMD_STATUS;
1264 *pstatus = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001265 channel->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001266 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1267 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001268 wait_event_timeout(channel->wait_vidstatus,
1269 (channel->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001270 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001271 if (channel->vidstatus_ready != 1) {
Dean Anderson4de39f52010-03-03 19:39:19 -03001272 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1273 res = -EFAULT;
1274 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001275 *pstatus = channel->vidstatus;
Dean Anderson4de39f52010-03-03 19:39:19 -03001276 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03001277 return res;
1278}
1279
Dean Anderson38f993a2008-06-26 23:15:51 -03001280static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1281{
1282 int res;
1283 struct s2255_fh *fh = priv;
1284 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001285 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001286 int j;
1287 dprintk(4, "%s\n", __func__);
1288 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1289 dev_err(&dev->udev->dev, "invalid fh type0\n");
1290 return -EINVAL;
1291 }
1292 if (i != fh->type) {
1293 dev_err(&dev->udev->dev, "invalid fh type1\n");
1294 return -EINVAL;
1295 }
1296
Dean Andersonfe85ce92010-06-01 19:12:07 -03001297 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001298 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001299 return -EBUSY;
1300 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001301 channel->last_frame = -1;
1302 channel->bad_payload = 0;
1303 channel->cur_frame = 0;
1304 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001305 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001306 channel->buffer.frame[j].ulState = S2255_READ_IDLE;
1307 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001308 }
1309 res = videobuf_streamon(&fh->vb_vidq);
1310 if (res == 0) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001311 s2255_start_acquire(channel);
1312 channel->b_acquire = 1;
1313 } else
1314 res_free(fh);
1315
Dean Anderson38f993a2008-06-26 23:15:51 -03001316 return res;
1317}
1318
1319static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1320{
Dean Anderson38f993a2008-06-26 23:15:51 -03001321 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001322 dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001323 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1324 printk(KERN_ERR "invalid fh type0\n");
1325 return -EINVAL;
1326 }
1327 if (i != fh->type) {
1328 printk(KERN_ERR "invalid type i\n");
1329 return -EINVAL;
1330 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001331 s2255_stop_acquire(fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001332 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001333 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001334 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001335}
1336
1337static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1338{
1339 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001340 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001341 struct videobuf_queue *q = &fh->vb_vidq;
1342 int ret = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001343 mutex_lock(&q->vb_lock);
1344 if (videobuf_queue_is_busy(q)) {
1345 dprintk(1, "queue busy\n");
1346 ret = -EBUSY;
1347 goto out_s_std;
1348 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001349 if (res_locked(fh)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001350 dprintk(1, "can't change standard after started\n");
1351 ret = -EBUSY;
1352 goto out_s_std;
1353 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001354 mode = fh->channel->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001355 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001356 dprintk(4, "%s NTSC\n", __func__);
1357 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001358 if (mode.format != FORMAT_NTSC) {
1359 mode.restart = 1;
1360 mode.format = FORMAT_NTSC;
1361 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001362 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001363 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001364 dprintk(4, "%s PAL\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001365 if (mode.format != FORMAT_PAL) {
1366 mode.restart = 1;
1367 mode.format = FORMAT_PAL;
1368 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001369 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001370 } else {
1371 ret = -EINVAL;
1372 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001373 if (mode.restart)
1374 s2255_set_mode(fh->channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001375out_s_std:
1376 mutex_unlock(&q->vb_lock);
1377 return ret;
1378}
1379
1380/* Sensoray 2255 is a multiple channel capture device.
1381 It does not have a "crossbar" of inputs.
1382 We use one V4L device per channel. The user must
1383 be aware that certain combinations are not allowed.
1384 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1385 at once in color(you can do full fps on 4 channels with greyscale.
1386*/
1387static int vidioc_enum_input(struct file *file, void *priv,
1388 struct v4l2_input *inp)
1389{
Dean Anderson4de39f52010-03-03 19:39:19 -03001390 struct s2255_fh *fh = priv;
1391 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001392 struct s2255_channel *channel = fh->channel;
Dean Anderson4de39f52010-03-03 19:39:19 -03001393 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001394 if (inp->index != 0)
1395 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001396 inp->type = V4L2_INPUT_TYPE_CAMERA;
1397 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001398 inp->status = 0;
1399 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1400 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001401 rc = s2255_cmd_status(fh->channel, &status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001402 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1403 if (rc == 0)
1404 inp->status = (status & 0x01) ? 0
1405 : V4L2_IN_ST_NO_SIGNAL;
1406 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001407 switch (dev->pid) {
1408 case 0x2255:
1409 default:
1410 strlcpy(inp->name, "Composite", sizeof(inp->name));
1411 break;
1412 case 0x2257:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001413 strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001414 sizeof(inp->name));
1415 break;
1416 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001417 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001418}
1419
1420static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1421{
1422 *i = 0;
1423 return 0;
1424}
1425static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1426{
1427 if (i > 0)
1428 return -EINVAL;
1429 return 0;
1430}
1431
1432/* --- controls ---------------------------------------------- */
1433static int vidioc_queryctrl(struct file *file, void *priv,
1434 struct v4l2_queryctrl *qc)
1435{
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001436 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001437 struct s2255_channel *channel = fh->channel;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001438 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001439 switch (qc->id) {
1440 case V4L2_CID_BRIGHTNESS:
1441 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1442 break;
1443 case V4L2_CID_CONTRAST:
1444 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1445 break;
1446 case V4L2_CID_SATURATION:
1447 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1448 break;
1449 case V4L2_CID_HUE:
1450 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1451 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001452 case V4L2_CID_PRIVATE_COLORFILTER:
1453 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1454 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001455 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001456 return -EINVAL;
1457 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1458 qc->type = V4L2_CTRL_TYPE_MENU;
1459 qc->minimum = 0;
1460 qc->maximum = 1;
1461 qc->step = 1;
1462 qc->default_value = 1;
1463 qc->flags = 0;
1464 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001465 default:
1466 return -EINVAL;
1467 }
1468 dprintk(4, "%s, id %d\n", __func__, qc->id);
1469 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001470}
1471
1472static int vidioc_g_ctrl(struct file *file, void *priv,
1473 struct v4l2_control *ctrl)
1474{
Dean Anderson2e70db92010-03-05 14:29:09 -03001475 struct s2255_fh *fh = priv;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001476 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001477 struct s2255_channel *channel = fh->channel;
Dean Anderson2e70db92010-03-05 14:29:09 -03001478 switch (ctrl->id) {
1479 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001480 ctrl->value = channel->mode.bright;
Dean Anderson2e70db92010-03-05 14:29:09 -03001481 break;
1482 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001483 ctrl->value = channel->mode.contrast;
Dean Anderson2e70db92010-03-05 14:29:09 -03001484 break;
1485 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001486 ctrl->value = channel->mode.saturation;
Dean Anderson2e70db92010-03-05 14:29:09 -03001487 break;
1488 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001489 ctrl->value = channel->mode.hue;
Dean Anderson2e70db92010-03-05 14:29:09 -03001490 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001491 case V4L2_CID_PRIVATE_COLORFILTER:
1492 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1493 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001494 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001495 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001496 ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001497 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001498 default:
1499 return -EINVAL;
1500 }
1501 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1502 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001503}
1504
1505static int vidioc_s_ctrl(struct file *file, void *priv,
1506 struct v4l2_control *ctrl)
1507{
Dean Anderson38f993a2008-06-26 23:15:51 -03001508 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001509 struct s2255_channel *channel = fh->channel;
1510 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
1511 struct s2255_mode mode;
1512 mode = channel->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001513 dprintk(4, "%s\n", __func__);
1514 /* update the mode to the corresponding value */
1515 switch (ctrl->id) {
1516 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001517 mode.bright = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001518 break;
1519 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001520 mode.contrast = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001521 break;
1522 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001523 mode.hue = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001524 break;
1525 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001526 mode.saturation = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001527 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001528 case V4L2_CID_PRIVATE_COLORFILTER:
1529 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1530 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001531 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001532 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001533 mode.color &= ~MASK_INPUT_TYPE;
1534 mode.color |= ((ctrl->value ? 0 : 1) << 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001535 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001536 default:
1537 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001538 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001539 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001540 /* set mode here. Note: stream does not need restarted.
1541 some V4L programs restart stream unnecessarily
1542 after a s_crtl.
1543 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001544 s2255_set_mode(fh->channel, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001545 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001546}
1547
Dean Anderson22b88d42008-08-29 15:33:19 -03001548static int vidioc_g_jpegcomp(struct file *file, void *priv,
1549 struct v4l2_jpegcompression *jc)
1550{
1551 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001552 struct s2255_channel *channel = fh->channel;
1553 *jc = channel->jc;
Dean Anderson85b85482010-04-08 23:51:17 -03001554 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001555 return 0;
1556}
1557
1558static int vidioc_s_jpegcomp(struct file *file, void *priv,
Hans Verkuild88aab52012-09-17 05:05:25 -03001559 const struct v4l2_jpegcompression *jc)
Dean Anderson22b88d42008-08-29 15:33:19 -03001560{
1561 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001562 struct s2255_channel *channel = fh->channel;
Dean Anderson22b88d42008-08-29 15:33:19 -03001563 if (jc->quality < 0 || jc->quality > 100)
1564 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001565 channel->jc.quality = jc->quality;
Dean Anderson85b85482010-04-08 23:51:17 -03001566 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001567 return 0;
1568}
Dean Anderson7d853532009-05-15 14:32:04 -03001569
1570static int vidioc_g_parm(struct file *file, void *priv,
1571 struct v4l2_streamparm *sp)
1572{
1573 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001574 __u32 def_num, def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001575 struct s2255_channel *channel = fh->channel;
Dean Anderson7d853532009-05-15 14:32:04 -03001576 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1577 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001578 memset(sp, 0, sizeof(struct v4l2_streamparm));
1579 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001580 sp->parm.capture.capturemode = channel->cap_parm.capturemode;
1581 def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1582 def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001583 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001584 switch (channel->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001585 default:
1586 case FDEC_1:
1587 sp->parm.capture.timeperframe.numerator = def_num;
1588 break;
1589 case FDEC_2:
1590 sp->parm.capture.timeperframe.numerator = def_num * 2;
1591 break;
1592 case FDEC_3:
1593 sp->parm.capture.timeperframe.numerator = def_num * 3;
1594 break;
1595 case FDEC_5:
1596 sp->parm.capture.timeperframe.numerator = def_num * 5;
1597 break;
1598 }
1599 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1600 sp->parm.capture.capturemode,
1601 sp->parm.capture.timeperframe.numerator,
1602 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001603 return 0;
1604}
1605
1606static int vidioc_s_parm(struct file *file, void *priv,
1607 struct v4l2_streamparm *sp)
1608{
1609 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001610 struct s2255_channel *channel = fh->channel;
1611 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001612 int fdec = FDEC_1;
1613 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001614 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1615 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001616 mode = channel->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001617 /* high quality capture mode requires a stream restart */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001618 if (channel->cap_parm.capturemode
1619 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001620 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001621 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1622 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001623 if (def_dem != sp->parm.capture.timeperframe.denominator)
1624 sp->parm.capture.timeperframe.numerator = def_num;
1625 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1626 sp->parm.capture.timeperframe.numerator = def_num;
1627 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1628 sp->parm.capture.timeperframe.numerator = def_num * 2;
1629 fdec = FDEC_2;
1630 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1631 sp->parm.capture.timeperframe.numerator = def_num * 3;
1632 fdec = FDEC_3;
1633 } else {
1634 sp->parm.capture.timeperframe.numerator = def_num * 5;
1635 fdec = FDEC_5;
1636 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001637 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001638 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001639 s2255_set_mode(channel, &mode);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001640 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1641 __func__,
1642 sp->parm.capture.capturemode,
1643 sp->parm.capture.timeperframe.numerator,
1644 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001645 return 0;
1646}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001647
1648static int vidioc_enum_frameintervals(struct file *file, void *priv,
1649 struct v4l2_frmivalenum *fe)
1650{
1651 int is_ntsc = 0;
1652#define NUM_FRAME_ENUMS 4
1653 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
1654 if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
1655 return -EINVAL;
1656 switch (fe->width) {
1657 case 640:
1658 if (fe->height != 240 && fe->height != 480)
1659 return -EINVAL;
1660 is_ntsc = 1;
1661 break;
1662 case 320:
1663 if (fe->height != 240)
1664 return -EINVAL;
1665 is_ntsc = 1;
1666 break;
1667 case 704:
1668 if (fe->height != 288 && fe->height != 576)
1669 return -EINVAL;
1670 break;
1671 case 352:
1672 if (fe->height != 288)
1673 return -EINVAL;
1674 break;
1675 default:
1676 return -EINVAL;
1677 }
1678 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1679 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1680 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1681 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1682 fe->discrete.denominator);
1683 return 0;
1684}
1685
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001686static int __s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001687{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001688 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001689 struct s2255_channel *channel = video_drvdata(file);
1690 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001691 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001692 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001693 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001694 dprintk(1, "s2255: open called (dev=%s)\n",
1695 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001696 state = atomic_read(&dev->fw_data->fw_state);
1697 switch (state) {
1698 case S2255_FW_DISCONNECTING:
Dean Andersonff7e22d2010-04-08 23:38:07 -03001699 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001700 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001701 s2255_dev_err(&dev->udev->dev,
1702 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001703 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001704 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001705 ((atomic_read(&dev->fw_data->fw_state)
1706 == S2255_FW_SUCCESS) ||
1707 (atomic_read(&dev->fw_data->fw_state)
1708 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001709 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001710 /* state may have changed, re-read */
1711 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001712 break;
1713 case S2255_FW_NOTLOADED:
1714 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001715 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1716 driver loaded and then device immediately opened */
1717 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1718 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001719 ((atomic_read(&dev->fw_data->fw_state)
1720 == S2255_FW_SUCCESS) ||
1721 (atomic_read(&dev->fw_data->fw_state)
1722 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001723 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001724 /* state may have changed, re-read */
1725 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001726 break;
1727 case S2255_FW_SUCCESS:
1728 default:
1729 break;
1730 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001731 /* state may have changed in above switch statement */
1732 switch (state) {
1733 case S2255_FW_SUCCESS:
1734 break;
1735 case S2255_FW_FAILED:
1736 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03001737 return -ENODEV;
1738 case S2255_FW_DISCONNECTING:
1739 printk(KERN_INFO "%s: disconnecting\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001740 return -ENODEV;
1741 case S2255_FW_LOADED_DSPWAIT:
1742 case S2255_FW_NOTLOADED:
1743 printk(KERN_INFO "%s: firmware not loaded yet"
1744 "please try again later\n",
1745 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001746 /*
1747 * Timeout on firmware load means device unusable.
1748 * Set firmware failure state.
1749 * On next s2255_open the firmware will be reloaded.
1750 */
1751 atomic_set(&dev->fw_data->fw_state,
1752 S2255_FW_FAILED);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001753 return -EAGAIN;
1754 default:
1755 printk(KERN_INFO "%s: unknown state\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001756 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001757 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001758 /* allocate + initialize per filehandle data */
1759 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001760 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001761 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03001762 file->private_data = fh;
1763 fh->dev = dev;
1764 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001765 fh->channel = channel;
1766 if (!channel->configured) {
1767 /* configure channel to default state */
1768 channel->fmt = &formats[0];
1769 s2255_set_mode(channel, &channel->mode);
1770 channel->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001771 }
Dean Anderson85b85482010-04-08 23:51:17 -03001772 dprintk(1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001773 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson85b85482010-04-08 23:51:17 -03001774 dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001775 (unsigned long)fh, (unsigned long)dev,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001776 (unsigned long)&channel->vidq);
Dean Anderson85b85482010-04-08 23:51:17 -03001777 dprintk(4, "%s: list_empty active=%d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001778 list_empty(&channel->vidq.active));
Dean Anderson38f993a2008-06-26 23:15:51 -03001779 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1780 NULL, &dev->slock,
1781 fh->type,
1782 V4L2_FIELD_INTERLACED,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001783 sizeof(struct s2255_buffer),
1784 fh, vdev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001785 return 0;
1786}
1787
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001788static int s2255_open(struct file *file)
1789{
1790 struct video_device *vdev = video_devdata(file);
1791 int ret;
1792
1793 if (mutex_lock_interruptible(vdev->lock))
1794 return -ERESTARTSYS;
1795 ret = __s2255_open(file);
1796 mutex_unlock(vdev->lock);
1797 return ret;
1798}
Dean Anderson38f993a2008-06-26 23:15:51 -03001799
1800static unsigned int s2255_poll(struct file *file,
1801 struct poll_table_struct *wait)
1802{
1803 struct s2255_fh *fh = file->private_data;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001804 struct s2255_dev *dev = fh->dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001805 int rc;
1806 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001807 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1808 return POLLERR;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001809 mutex_lock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001810 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001811 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001812 return rc;
1813}
1814
Dean Andersond62e85a2010-04-09 19:54:26 -03001815static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001816{
Dean Anderson38f993a2008-06-26 23:15:51 -03001817 /* board shutdown stops the read pipe if it is running */
1818 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001819 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001820 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001821 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001822 usb_kill_urb(dev->fw_data->fw_urb);
1823 usb_free_urb(dev->fw_data->fw_urb);
1824 dev->fw_data->fw_urb = NULL;
1825 }
Jesper Juhl3fc82fa2012-04-09 16:50:04 -03001826 release_firmware(dev->fw_data->fw);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001827 kfree(dev->fw_data->pfw_data);
1828 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001829 /* reset the DSP so firmware can be reloaded next time */
1830 s2255_reset_dsppower(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001831 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001832 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001833 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001834 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001835 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001836}
1837
Dean Andersonff7e22d2010-04-08 23:38:07 -03001838static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001839{
1840 struct s2255_fh *fh = file->private_data;
1841 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001842 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001843 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001844 if (!dev)
1845 return -ENODEV;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001846 mutex_lock(&dev->lock);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001847 /* turn off stream */
1848 if (res_check(fh)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001849 if (channel->b_acquire)
1850 s2255_stop_acquire(fh->channel);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001851 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001852 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001853 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001854 videobuf_mmap_free(&fh->vb_vidq);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001855 mutex_unlock(&dev->lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001856 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001857 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001858 return 0;
1859}
1860
1861static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1862{
1863 struct s2255_fh *fh = file->private_data;
Julia Lawalle8397762012-08-14 11:49:46 -03001864 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001865 int ret;
1866
1867 if (!fh)
1868 return -ENODEV;
Julia Lawalle8397762012-08-14 11:49:46 -03001869 dev = fh->dev;
Dean Anderson85b85482010-04-08 23:51:17 -03001870 dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001871 if (mutex_lock_interruptible(&dev->lock))
1872 return -ERESTARTSYS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001873 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001874 mutex_unlock(&dev->lock);
Dean Anderson85b85482010-04-08 23:51:17 -03001875 dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001876 (unsigned long)vma->vm_start,
1877 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001878 return ret;
1879}
1880
Hans Verkuilbec43662008-12-30 06:58:20 -03001881static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001882 .owner = THIS_MODULE,
1883 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001884 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001885 .poll = s2255_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001886 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001887 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001888};
1889
Hans Verkuila3998102008-07-21 02:57:38 -03001890static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001891 .vidioc_querymenu = vidioc_querymenu,
Dean Anderson38f993a2008-06-26 23:15:51 -03001892 .vidioc_querycap = vidioc_querycap,
1893 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1894 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1895 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1896 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1897 .vidioc_reqbufs = vidioc_reqbufs,
1898 .vidioc_querybuf = vidioc_querybuf,
1899 .vidioc_qbuf = vidioc_qbuf,
1900 .vidioc_dqbuf = vidioc_dqbuf,
1901 .vidioc_s_std = vidioc_s_std,
1902 .vidioc_enum_input = vidioc_enum_input,
1903 .vidioc_g_input = vidioc_g_input,
1904 .vidioc_s_input = vidioc_s_input,
1905 .vidioc_queryctrl = vidioc_queryctrl,
1906 .vidioc_g_ctrl = vidioc_g_ctrl,
1907 .vidioc_s_ctrl = vidioc_s_ctrl,
1908 .vidioc_streamon = vidioc_streamon,
1909 .vidioc_streamoff = vidioc_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001910 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1911 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001912 .vidioc_s_parm = vidioc_s_parm,
1913 .vidioc_g_parm = vidioc_g_parm,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001914 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuila3998102008-07-21 02:57:38 -03001915};
1916
Dean Andersonff7e22d2010-04-08 23:38:07 -03001917static void s2255_video_device_release(struct video_device *vdev)
1918{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001919 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
1920 dprintk(4, "%s, chnls: %d \n", __func__,
1921 atomic_read(&dev->num_channels));
1922 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001923 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001924 return;
1925}
1926
Hans Verkuila3998102008-07-21 02:57:38 -03001927static struct video_device template = {
1928 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001929 .fops = &s2255_fops_v4l,
1930 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001931 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001932 .tvnorms = S2255_NORMS,
1933 .current_norm = V4L2_STD_NTSC_M,
1934};
1935
1936static int s2255_probe_v4l(struct s2255_dev *dev)
1937{
1938 int ret;
1939 int i;
1940 int cur_nr = video_nr;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001941 struct s2255_channel *channel;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001942 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1943 if (ret)
1944 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001945 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001946 /* register 4 video devices */
1947 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001948 channel = &dev->channel[i];
1949 INIT_LIST_HEAD(&channel->vidq.active);
1950 channel->vidq.dev = dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001951 /* register 4 video devices */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001952 channel->vdev = template;
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001953 channel->vdev.lock = &dev->lock;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001954 channel->vdev.v4l2_dev = &dev->v4l2_dev;
1955 video_set_drvdata(&channel->vdev, channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03001956 if (video_nr == -1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001957 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001958 VFL_TYPE_GRABBER,
1959 video_nr);
1960 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001961 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001962 VFL_TYPE_GRABBER,
1963 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001964
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001965 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001966 dev_err(&dev->udev->dev,
1967 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001968 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001969 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001970 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001971 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001972 video_device_node_name(&channel->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001973
Dean Anderson38f993a2008-06-26 23:15:51 -03001974 }
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03001975 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %s\n",
1976 S2255_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001977 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001978 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001979 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001980 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001981 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001982 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001983 printk(KERN_WARNING "s2255: Not all channels available.\n");
1984 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001985}
1986
Dean Anderson38f993a2008-06-26 23:15:51 -03001987/* this function moves the usb stream read pipe data
1988 * into the system buffers.
1989 * returns 0 on success, EAGAIN if more data to process( call this
1990 * function again).
1991 *
1992 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001993 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001994 * bytes 4-7: channel: 0-3
1995 * bytes 8-11: payload size: size of the frame
1996 * bytes 12-payloadsize+12: frame data
1997 */
1998static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1999{
Dean Anderson38f993a2008-06-26 23:15:51 -03002000 char *pdest;
2001 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002002 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002003 char *psrc;
2004 unsigned long copy_size;
2005 unsigned long size;
2006 s32 idx = -1;
2007 struct s2255_framei *frm;
2008 unsigned char *pdata;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002009 struct s2255_channel *channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03002010 dprintk(100, "buffer to user\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002011 channel = &dev->channel[dev->cc];
2012 idx = channel->cur_frame;
2013 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002014 if (frm->ulState == S2255_READ_IDLE) {
2015 int jj;
2016 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03002017 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03002018 int payload;
2019 /* search for marker codes */
2020 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03002021 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002022 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03002023 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03002024 case S2255_MARKER_FRAME:
Dean Anderson14d96262008-08-25 13:58:55 -03002025 dprintk(4, "found frame marker at offset:"
2026 " %d [%x %x]\n", jj, pdata[0],
2027 pdata[1]);
2028 offset = jj + PREFIX_SIZE;
2029 bframe = 1;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002030 cc = le32_to_cpu(pdword[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03002031 if (cc >= MAX_CHANNELS) {
2032 printk(KERN_ERR
2033 "bad channel\n");
2034 return -EINVAL;
2035 }
2036 /* reverse it */
2037 dev->cc = G_chnmap[cc];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002038 channel = &dev->channel[dev->cc];
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002039 payload = le32_to_cpu(pdword[3]);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002040 if (payload > channel->req_image_size) {
2041 channel->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03002042 /* discard the bad frame */
2043 return -EINVAL;
2044 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002045 channel->pkt_size = payload;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002046 channel->jpg_size = le32_to_cpu(pdword[4]);
Dean Anderson14d96262008-08-25 13:58:55 -03002047 break;
2048 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002049
Dean Anderson14d96262008-08-25 13:58:55 -03002050 pdata += DEF_USB_BLOCK;
2051 jj += DEF_USB_BLOCK;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002052 if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002053 break;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002054 cc = G_chnmap[le32_to_cpu(pdword[1])];
Roel Kluinf14a2972009-10-23 07:59:42 -03002055 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002056 break;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002057 channel = &dev->channel[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002058 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03002059 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03002060 /* check if channel valid */
2061 /* set mode ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002062 channel->setmode_ready = 1;
2063 wake_up(&channel->wait_setmode);
Dean Anderson14d96262008-08-25 13:58:55 -03002064 dprintk(5, "setmode ready %d\n", cc);
2065 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002066 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002067 dev->chn_ready |= (1 << cc);
2068 if ((dev->chn_ready & 0x0f) != 0x0f)
2069 break;
2070 /* all channels ready */
2071 printk(KERN_INFO "s2255: fw loaded\n");
2072 atomic_set(&dev->fw_data->fw_state,
2073 S2255_FW_SUCCESS);
2074 wake_up(&dev->fw_data->wait_fw);
2075 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002076 case S2255_RESPONSE_STATUS:
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002077 channel->vidstatus = le32_to_cpu(pdword[3]);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002078 channel->vidstatus_ready = 1;
2079 wake_up(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002080 dprintk(5, "got vidstatus %x chan %d\n",
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002081 le32_to_cpu(pdword[3]), cc);
Dean Anderson4de39f52010-03-03 19:39:19 -03002082 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002083 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02002084 printk(KERN_INFO "s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002085 }
2086 default:
2087 pdata++;
2088 break;
2089 }
2090 if (bframe)
2091 break;
2092 } /* for */
2093 if (!bframe)
2094 return -EINVAL;
2095 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002096 channel = &dev->channel[dev->cc];
2097 idx = channel->cur_frame;
2098 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002099 /* search done. now find out if should be acquiring on this channel */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002100 if (!channel->b_acquire) {
Dean Anderson14d96262008-08-25 13:58:55 -03002101 /* we found a frame, but this channel is turned off */
2102 frm->ulState = S2255_READ_IDLE;
2103 return -EINVAL;
2104 }
2105
2106 if (frm->ulState == S2255_READ_IDLE) {
2107 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002108 frm->cur_size = 0;
2109 }
2110
Dean Anderson14d96262008-08-25 13:58:55 -03002111 /* skip the marker 512 bytes (and offset if out of sync) */
2112 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2113
Dean Anderson38f993a2008-06-26 23:15:51 -03002114
2115 if (frm->lpvbits == NULL) {
2116 dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
2117 frm, dev, dev->cc, idx);
2118 return -ENOMEM;
2119 }
2120
2121 pdest = frm->lpvbits + frm->cur_size;
2122
Dean Anderson14d96262008-08-25 13:58:55 -03002123 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002124
Dean Andersonfe85ce92010-06-01 19:12:07 -03002125 size = channel->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002126
Dean Anderson14d96262008-08-25 13:58:55 -03002127 /* sanity check on pdest */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002128 if ((copy_size + frm->cur_size) < channel->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03002129 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002130
Dean Anderson38f993a2008-06-26 23:15:51 -03002131 frm->cur_size += copy_size;
Dean Anderson14d96262008-08-25 13:58:55 -03002132 dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002133
Dean Anderson14d96262008-08-25 13:58:55 -03002134 if (frm->cur_size >= size) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002135 dprintk(2, "****************[%d]Buffer[%d]full*************\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002136 dev->cc, idx);
2137 channel->last_frame = channel->cur_frame;
2138 channel->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002139 /* end of system frame ring buffer, start at zero */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002140 if ((channel->cur_frame == SYS_FRAMES) ||
2141 (channel->cur_frame == channel->buffer.dwFrames))
2142 channel->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002143 /* frame ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002144 if (channel->b_acquire)
2145 s2255_got_frame(channel, channel->jpg_size);
2146 channel->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03002147 frm->ulState = S2255_READ_IDLE;
2148 frm->cur_size = 0;
2149
Dean Anderson38f993a2008-06-26 23:15:51 -03002150 }
2151 /* done successfully */
2152 return 0;
2153}
2154
2155static void s2255_read_video_callback(struct s2255_dev *dev,
2156 struct s2255_pipeinfo *pipe_info)
2157{
2158 int res;
2159 dprintk(50, "callback read video \n");
2160
2161 if (dev->cc >= MAX_CHANNELS) {
2162 dev->cc = 0;
2163 dev_err(&dev->udev->dev, "invalid channel\n");
2164 return;
2165 }
2166 /* otherwise copy to the system buffers */
2167 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002168 if (res != 0)
2169 dprintk(4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002170
2171 dprintk(50, "callback read video done\n");
2172 return;
2173}
2174
2175static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2176 u16 Index, u16 Value, void *TransferBuffer,
2177 s32 TransferBufferLength, int bOut)
2178{
2179 int r;
2180 if (!bOut) {
2181 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2182 Request,
2183 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2184 USB_DIR_IN,
2185 Value, Index, TransferBuffer,
2186 TransferBufferLength, HZ * 5);
2187 } else {
2188 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2189 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2190 Value, Index, TransferBuffer,
2191 TransferBufferLength, HZ * 5);
2192 }
2193 return r;
2194}
2195
2196/*
2197 * retrieve FX2 firmware version. future use.
2198 * @param dev pointer to device extension
2199 * @return -1 for fail, else returns firmware version as an int(16 bits)
2200 */
2201static int s2255_get_fx2fw(struct s2255_dev *dev)
2202{
2203 int fw;
2204 int ret;
2205 unsigned char transBuffer[64];
2206 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2207 S2255_VR_IN);
2208 if (ret < 0)
2209 dprintk(2, "get fw error: %x\n", ret);
2210 fw = transBuffer[0] + (transBuffer[1] << 8);
2211 dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
2212 return fw;
2213}
2214
2215/*
2216 * Create the system ring buffer to copy frames into from the
2217 * usb read pipe.
2218 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002219static int s2255_create_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002220{
2221 unsigned long i;
2222 unsigned long reqsize;
2223 dprintk(1, "create sys buffers\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002224 channel->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03002225 /* always allocate maximum size(PAL) for system buffers */
2226 reqsize = SYS_FRAMES_MAXSIZE;
2227
2228 if (reqsize > SYS_FRAMES_MAXSIZE)
2229 reqsize = SYS_FRAMES_MAXSIZE;
2230
2231 for (i = 0; i < SYS_FRAMES; i++) {
2232 /* allocate the frames */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002233 channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
2234 dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
2235 &channel->buffer.frame[i], channel->idx, i,
2236 channel->buffer.frame[i].lpvbits);
2237 channel->buffer.frame[i].size = reqsize;
2238 if (channel->buffer.frame[i].lpvbits == NULL) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002239 printk(KERN_INFO "out of memory. using less frames\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002240 channel->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002241 break;
2242 }
2243 }
2244
2245 /* make sure internal states are set */
2246 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002247 channel->buffer.frame[i].ulState = 0;
2248 channel->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002249 }
2250
Dean Andersonfe85ce92010-06-01 19:12:07 -03002251 channel->cur_frame = 0;
2252 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002253 return 0;
2254}
2255
Dean Andersonfe85ce92010-06-01 19:12:07 -03002256static int s2255_release_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002257{
2258 unsigned long i;
2259 dprintk(1, "release sys buffers\n");
2260 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002261 if (channel->buffer.frame[i].lpvbits) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002262 dprintk(1, "vfree %p\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002263 channel->buffer.frame[i].lpvbits);
2264 vfree(channel->buffer.frame[i].lpvbits);
Dean Anderson38f993a2008-06-26 23:15:51 -03002265 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002266 channel->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002267 }
2268 return 0;
2269}
2270
2271static int s2255_board_init(struct s2255_dev *dev)
2272{
Dean Anderson38f993a2008-06-26 23:15:51 -03002273 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2274 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002275 int j;
2276 struct s2255_pipeinfo *pipe = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002277 dprintk(4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002278 memset(pipe, 0, sizeof(*pipe));
2279 pipe->dev = dev;
2280 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2281 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002282
Dean Andersonab85c6a2010-04-08 23:39:12 -03002283 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2284 GFP_KERNEL);
2285 if (pipe->transfer_buffer == NULL) {
2286 dprintk(1, "out of memory!\n");
2287 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002288 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002289 /* query the firmware */
2290 fw_ver = s2255_get_fx2fw(dev);
2291
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -03002292 printk(KERN_INFO "s2255: usb firmware version %d.%d\n",
Dean Andersonabce21f2009-04-23 16:04:41 -03002293 (fw_ver >> 8) & 0xff,
2294 fw_ver & 0xff);
2295
2296 if (fw_ver < S2255_CUR_USB_FWVER)
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -03002297 printk(KERN_INFO "s2255: newer USB firmware available\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002298
2299 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002300 struct s2255_channel *channel = &dev->channel[j];
2301 channel->b_acquire = 0;
2302 channel->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002303 if (dev->pid == 0x2257 && j > 1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002304 channel->mode.color |= (1 << 16);
2305 channel->jc.quality = S2255_DEF_JPEG_QUAL;
2306 channel->width = LINE_SZ_4CIFS_NTSC;
2307 channel->height = NUM_LINES_4CIFS_NTSC * 2;
2308 channel->fmt = &formats[0];
2309 channel->mode.restart = 1;
2310 channel->req_image_size = get_transfer_size(&mode_def);
2311 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002312 /* create the system buffers */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002313 s2255_create_sys_buffers(channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03002314 }
2315 /* start read pipe */
2316 s2255_start_readpipe(dev);
Dean Anderson85b85482010-04-08 23:51:17 -03002317 dprintk(1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002318 return 0;
2319}
2320
2321static int s2255_board_shutdown(struct s2255_dev *dev)
2322{
2323 u32 i;
Dean Anderson85b85482010-04-08 23:51:17 -03002324 dprintk(1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002325
2326 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002327 if (dev->channel[i].b_acquire)
2328 s2255_stop_acquire(&dev->channel[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002329 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002330 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002331 for (i = 0; i < MAX_CHANNELS; i++)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002332 s2255_release_sys_buffers(&dev->channel[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002333 /* release transfer buffer */
2334 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002335 return 0;
2336}
2337
2338static void read_pipe_completion(struct urb *purb)
2339{
2340 struct s2255_pipeinfo *pipe_info;
2341 struct s2255_dev *dev;
2342 int status;
2343 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002344 pipe_info = purb->context;
Dean Anderson85b85482010-04-08 23:51:17 -03002345 dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
Dean Anderson38f993a2008-06-26 23:15:51 -03002346 purb->status);
2347 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002348 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002349 return;
2350 }
2351
2352 dev = pipe_info->dev;
2353 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002354 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002355 return;
2356 }
2357 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002358 /* if shutting down, do not resubmit, exit immediately */
2359 if (status == -ESHUTDOWN) {
Dean Anderson85b85482010-04-08 23:51:17 -03002360 dprintk(2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002361 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002362 return;
2363 }
2364
2365 if (pipe_info->state == 0) {
Dean Anderson85b85482010-04-08 23:51:17 -03002366 dprintk(2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002367 return;
2368 }
2369
Dean Andersonb02064c2009-04-30 12:29:38 -03002370 if (status == 0)
2371 s2255_read_video_callback(dev, pipe_info);
2372 else {
2373 pipe_info->err_count++;
Dean Anderson85b85482010-04-08 23:51:17 -03002374 dprintk(1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002375 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002376
Dean Anderson38f993a2008-06-26 23:15:51 -03002377 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2378 /* reuse urb */
2379 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2380 pipe,
2381 pipe_info->transfer_buffer,
2382 pipe_info->cur_transfer_size,
2383 read_pipe_completion, pipe_info);
2384
2385 if (pipe_info->state != 0) {
Pete Eberleina1b4c862011-04-01 21:21:26 -03002386 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002387 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002388 }
2389 } else {
Dean Anderson85b85482010-04-08 23:51:17 -03002390 dprintk(2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002391 }
2392 return;
2393}
2394
2395static int s2255_start_readpipe(struct s2255_dev *dev)
2396{
2397 int pipe;
2398 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002399 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002400 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
Dean Anderson85b85482010-04-08 23:51:17 -03002401 dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002402 pipe_info->state = 1;
2403 pipe_info->err_count = 0;
2404 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2405 if (!pipe_info->stream_urb) {
2406 dev_err(&dev->udev->dev,
2407 "ReadStream: Unable to alloc URB\n");
2408 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002409 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002410 /* transfer buffer allocated in board_init */
2411 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2412 pipe,
2413 pipe_info->transfer_buffer,
2414 pipe_info->cur_transfer_size,
2415 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002416 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2417 if (retval) {
2418 printk(KERN_ERR "s2255: start read pipe failed\n");
2419 return retval;
2420 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002421 return 0;
2422}
2423
2424/* starts acquisition process */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002425static int s2255_start_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002426{
2427 unsigned char *buffer;
2428 int res;
2429 unsigned long chn_rev;
2430 int j;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002431 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2432 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002433 buffer = kzalloc(512, GFP_KERNEL);
2434 if (buffer == NULL) {
2435 dev_err(&dev->udev->dev, "out of mem\n");
2436 return -ENOMEM;
2437 }
2438
Dean Andersonfe85ce92010-06-01 19:12:07 -03002439 channel->last_frame = -1;
2440 channel->bad_payload = 0;
2441 channel->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002442 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002443 channel->buffer.frame[j].ulState = 0;
2444 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002445 }
2446
2447 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002448 *(__le32 *) buffer = IN_DATA_TOKEN;
2449 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2450 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002451 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2452 if (res != 0)
2453 dev_err(&dev->udev->dev, "CMD_START error\n");
2454
Dean Andersonfe85ce92010-06-01 19:12:07 -03002455 dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03002456 kfree(buffer);
2457 return 0;
2458}
2459
Dean Andersonfe85ce92010-06-01 19:12:07 -03002460static int s2255_stop_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002461{
2462 unsigned char *buffer;
2463 int res;
2464 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002465 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2466 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002467 buffer = kzalloc(512, GFP_KERNEL);
2468 if (buffer == NULL) {
2469 dev_err(&dev->udev->dev, "out of mem\n");
2470 return -ENOMEM;
2471 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002472 /* send the stop command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002473 *(__le32 *) buffer = IN_DATA_TOKEN;
2474 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2475 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002476 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002477 if (res != 0)
2478 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002479 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002480 channel->b_acquire = 0;
2481 dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
Dean Anderson14d96262008-08-25 13:58:55 -03002482 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002483}
2484
2485static void s2255_stop_readpipe(struct s2255_dev *dev)
2486{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002487 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002488
Dean Andersonab85c6a2010-04-08 23:39:12 -03002489 pipe->state = 0;
2490 if (pipe->stream_urb) {
2491 /* cancel urb */
2492 usb_kill_urb(pipe->stream_urb);
2493 usb_free_urb(pipe->stream_urb);
2494 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002495 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002496 dprintk(4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002497 return;
2498}
2499
Dean Anderson14d96262008-08-25 13:58:55 -03002500static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002501{
Dean Anderson14d96262008-08-25 13:58:55 -03002502 if (reset)
2503 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002504 dev->fw_data->fw_size = dev->fw_data->fw->size;
2505 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2506 memcpy(dev->fw_data->pfw_data,
2507 dev->fw_data->fw->data, CHUNK_SIZE);
2508 dev->fw_data->fw_loaded = CHUNK_SIZE;
2509 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2510 usb_sndbulkpipe(dev->udev, 2),
2511 dev->fw_data->pfw_data,
2512 CHUNK_SIZE, s2255_fwchunk_complete,
2513 dev->fw_data);
2514 mod_timer(&dev->timer, jiffies + HZ);
2515}
2516
2517/* standard usb probe function */
2518static int s2255_probe(struct usb_interface *interface,
2519 const struct usb_device_id *id)
2520{
2521 struct s2255_dev *dev = NULL;
2522 struct usb_host_interface *iface_desc;
2523 struct usb_endpoint_descriptor *endpoint;
2524 int i;
2525 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002526 __le32 *pdata;
2527 int fw_size;
Dean Anderson85b85482010-04-08 23:51:17 -03002528 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002529 /* allocate memory for our device state and initialize it to zero */
2530 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2531 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002532 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002533 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002534 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002535 atomic_set(&dev->num_channels, 0);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002536 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002537 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2538 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002539 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002540 mutex_init(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002541 /* grab usb_device and save it */
2542 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2543 if (dev->udev == NULL) {
2544 dev_err(&interface->dev, "null usb device\n");
2545 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002546 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002547 }
Dean Andersond62e85a2010-04-09 19:54:26 -03002548 dprintk(1, "dev: %p, udev %p interface %p\n", dev,
Dean Anderson38f993a2008-06-26 23:15:51 -03002549 dev->udev, interface);
2550 dev->interface = interface;
2551 /* set up the endpoint information */
2552 iface_desc = interface->cur_altsetting;
2553 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2554 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2555 endpoint = &iface_desc->endpoint[i].desc;
2556 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2557 /* we found the bulk in endpoint */
2558 dev->read_endpoint = endpoint->bEndpointAddress;
2559 }
2560 }
2561
2562 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002563 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002564 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002565 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002566 init_timer(&dev->timer);
2567 dev->timer.function = s2255_timer;
2568 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002569 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002570 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002571 struct s2255_channel *channel = &dev->channel[i];
2572 dev->channel[i].idx = i;
2573 init_waitqueue_head(&channel->wait_setmode);
2574 init_waitqueue_head(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002575 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002576
2577 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002578 if (!dev->fw_data->fw_urb) {
2579 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002580 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002581 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002582
Dean Anderson38f993a2008-06-26 23:15:51 -03002583 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2584 if (!dev->fw_data->pfw_data) {
2585 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002586 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002587 }
2588 /* load the first chunk */
2589 if (request_firmware(&dev->fw_data->fw,
2590 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2591 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002592 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002593 }
Dean Anderson14d96262008-08-25 13:58:55 -03002594 /* check the firmware is valid */
2595 fw_size = dev->fw_data->fw->size;
2596 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002597
Dean Anderson14d96262008-08-25 13:58:55 -03002598 if (*pdata != S2255_FW_MARKER) {
2599 printk(KERN_INFO "Firmware invalid.\n");
2600 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002601 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002602 } else {
2603 /* make sure firmware is the latest */
2604 __le32 *pRel;
2605 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2606 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002607 dev->dsp_fw_ver = le32_to_cpu(*pRel);
2608 if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
Dean Anderson4de39f52010-03-03 19:39:19 -03002609 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002610 if (dev->pid == 0x2257 &&
2611 dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002612 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
Dean Andersonfe85ce92010-06-01 19:12:07 -03002613 " or above.\n", S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002614 }
Dean Anderson14d96262008-08-25 13:58:55 -03002615 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002616 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002617 retval = s2255_board_init(dev);
2618 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002619 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002620 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002621 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002622 /* loads v4l specific */
2623 retval = s2255_probe_v4l(dev);
2624 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002625 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002626 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2627 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002628errorBOARDINIT:
2629 s2255_board_shutdown(dev);
2630errorFWMARKER:
2631 release_firmware(dev->fw_data->fw);
2632errorREQFW:
2633 kfree(dev->fw_data->pfw_data);
2634errorFWDATA2:
2635 usb_free_urb(dev->fw_data->fw_urb);
2636errorFWURB:
2637 del_timer(&dev->timer);
2638errorEP:
2639 usb_put_dev(dev->udev);
2640errorUDEV:
2641 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002642 mutex_destroy(&dev->lock);
2643errorFWDATA1:
2644 kfree(dev);
2645 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002646 return retval;
2647}
2648
2649/* disconnect routine. when board is removed physically or with rmmod */
2650static void s2255_disconnect(struct usb_interface *interface)
2651{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002652 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002653 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002654 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002655 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002656 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002657 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002658 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002659 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002660 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002661 for (i = 0; i < channels; i++)
2662 video_unregister_device(&dev->channel[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002663 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002664 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2665 wake_up(&dev->fw_data->wait_fw);
2666 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002667 dev->channel[i].setmode_ready = 1;
2668 wake_up(&dev->channel[i].wait_setmode);
2669 dev->channel[i].vidstatus_ready = 1;
2670 wake_up(&dev->channel[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002671 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002672 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002673 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002674 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002675}
2676
2677static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002678 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002679 .probe = s2255_probe,
2680 .disconnect = s2255_disconnect,
2681 .id_table = s2255_table,
2682};
2683
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002684module_usb_driver(s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002685
2686MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2687MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2688MODULE_LICENSE("GPL");
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03002689MODULE_VERSION(S2255_VERSION);
Tim Gardner1bec9822012-07-24 16:52:27 -03002690MODULE_FIRMWARE(FIRMWARE_FILE_NAME);