blob: c1bef61876610e7ebb961c8ff11c76b986485bf5 [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)
137#define CMD_2255 cpu_to_le32(0xc2255000)
138#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 mutex open_lock;
Dean Anderson38f993a2008-06-26 23:15:51 -0300262 struct usb_device *udev;
263 struct usb_interface *interface;
264 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300265 struct timer_list timer;
266 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300267 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300268 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300269 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300270 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300271 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300272 /* dsp firmware version (f2255usb.bin) */
273 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300274 u16 pid; /* product id */
Dean Anderson38f993a2008-06-26 23:15:51 -0300275};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300276
Dean Anderson65c6edb2010-04-20 17:21:32 -0300277static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
278{
279 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
280}
Dean Anderson38f993a2008-06-26 23:15:51 -0300281
282struct s2255_fmt {
283 char *name;
284 u32 fourcc;
285 int depth;
286};
287
288/* buffer for one video frame */
289struct s2255_buffer {
290 /* common v4l buffer stuff -- must be first */
291 struct videobuf_buffer vb;
292 const struct s2255_fmt *fmt;
293};
294
295struct s2255_fh {
296 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300297 struct videobuf_queue vb_vidq;
298 enum v4l2_buf_type type;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300299 struct s2255_channel *channel;
300 int resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300301};
302
Dean Andersonabce21f2009-04-23 16:04:41 -0300303/* current cypress EEPROM firmware version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300304#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
Dean Anderson4de39f52010-03-03 19:39:19 -0300305/* current DSP FW version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300306#define S2255_CUR_DSP_FWVER 10104
Dean Anderson4de39f52010-03-03 19:39:19 -0300307/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300308#define S2255_MIN_DSP_STATUS 5
309#define S2255_MIN_DSP_COLORFILTER 8
Dean Anderson38f993a2008-06-26 23:15:51 -0300310#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300311
312/* private V4L2 controls */
313
314/*
315 * The following chart displays how COLORFILTER should be set
316 * =========================================================
317 * = fourcc = COLORFILTER =
318 * = ===============================
319 * = = 0 = 1 =
320 * =========================================================
321 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
322 * = = s-video or = composite =
323 * = = B/W camera = input =
324 * =========================================================
325 * = other = color, svideo = color, =
326 * = = = composite =
327 * =========================================================
328 *
329 * Notes:
330 * channels 0-3 on 2255 are composite
331 * channels 0-1 on 2257 are composite, 2-3 are s-video
332 * If COLORFILTER is 0 with a composite color camera connected,
333 * the output will appear monochrome but hatching
334 * will occur.
335 * COLORFILTER is different from "color killer" and "color effects"
336 * for reasons above.
337 */
338#define S2255_V4L2_YC_ON 1
339#define S2255_V4L2_YC_OFF 0
340#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
341
Dean Anderson38f993a2008-06-26 23:15:51 -0300342/* frame prefix size (sent once every frame) */
343#define PREFIX_SIZE 512
344
345/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300346static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300347
Dean Anderson38f993a2008-06-26 23:15:51 -0300348static int debug;
349static int *s2255_debug = &debug;
350
351static int s2255_start_readpipe(struct s2255_dev *dev);
352static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300353static int s2255_start_acquire(struct s2255_channel *channel);
354static int s2255_stop_acquire(struct s2255_channel *channel);
355static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
356 int jpgsize);
357static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300358static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300359static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300360static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300361static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
362 u16 index, u16 value, void *buf,
363 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300364
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300365/* dev_err macro with driver name */
366#define S2255_DRIVER_NAME "s2255"
367#define s2255_dev_err(dev, fmt, arg...) \
368 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
369
Dean Anderson38f993a2008-06-26 23:15:51 -0300370#define dprintk(level, fmt, arg...) \
371 do { \
372 if (*s2255_debug >= (level)) { \
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300373 printk(KERN_DEBUG S2255_DRIVER_NAME \
374 ": " fmt, ##arg); \
Dean Anderson38f993a2008-06-26 23:15:51 -0300375 } \
376 } while (0)
377
Dean Anderson38f993a2008-06-26 23:15:51 -0300378static struct usb_driver s2255_driver;
379
Dean Anderson38f993a2008-06-26 23:15:51 -0300380/* Declare static vars that will be used as parameters */
381static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
382
383/* start video number */
384static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
385
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300386/* Enable jpeg capture. */
387static int jpeg_enable = 1;
388
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300389module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300390MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300391module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300392MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300393module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300394MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300395module_param(jpeg_enable, int, 0644);
396MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
Dean Anderson38f993a2008-06-26 23:15:51 -0300397
398/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300399#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300400static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300401 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
402 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300403 { } /* Terminating entry */
404};
405MODULE_DEVICE_TABLE(usb, s2255_table);
406
Dean Anderson38f993a2008-06-26 23:15:51 -0300407#define BUFFER_TIMEOUT msecs_to_jiffies(400)
408
Dean Anderson38f993a2008-06-26 23:15:51 -0300409/* image formats. */
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300410/* JPEG formats must be defined last to support jpeg_enable parameter */
Dean Anderson38f993a2008-06-26 23:15:51 -0300411static const struct s2255_fmt formats[] = {
412 {
413 .name = "4:2:2, planar, YUV422P",
414 .fourcc = V4L2_PIX_FMT_YUV422P,
415 .depth = 16
416
417 }, {
418 .name = "4:2:2, packed, YUYV",
419 .fourcc = V4L2_PIX_FMT_YUYV,
420 .depth = 16
421
422 }, {
423 .name = "4:2:2, packed, UYVY",
424 .fourcc = V4L2_PIX_FMT_UYVY,
425 .depth = 16
426 }, {
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300427 .name = "8bpp GREY",
428 .fourcc = V4L2_PIX_FMT_GREY,
429 .depth = 8
430 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300431 .name = "JPG",
432 .fourcc = V4L2_PIX_FMT_JPEG,
433 .depth = 24
434 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300435 .name = "MJPG",
436 .fourcc = V4L2_PIX_FMT_MJPEG,
437 .depth = 24
Dean Anderson38f993a2008-06-26 23:15:51 -0300438 }
439};
440
441static int norm_maxw(struct video_device *vdev)
442{
443 return (vdev->current_norm & V4L2_STD_NTSC) ?
444 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
445}
446
447static int norm_maxh(struct video_device *vdev)
448{
449 return (vdev->current_norm & V4L2_STD_NTSC) ?
450 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
451}
452
453static int norm_minw(struct video_device *vdev)
454{
455 return (vdev->current_norm & V4L2_STD_NTSC) ?
456 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
457}
458
459static int norm_minh(struct video_device *vdev)
460{
461 return (vdev->current_norm & V4L2_STD_NTSC) ?
462 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
463}
464
465
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300466/*
467 * TODO: fixme: move YUV reordering to hardware
468 * converts 2255 planar format to yuyv or uyvy
469 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300470static void planar422p_to_yuv_packed(const unsigned char *in,
471 unsigned char *out,
472 int width, int height,
473 int fmt)
474{
475 unsigned char *pY;
476 unsigned char *pCb;
477 unsigned char *pCr;
478 unsigned long size = height * width;
479 unsigned int i;
480 pY = (unsigned char *)in;
481 pCr = (unsigned char *)in + height * width;
482 pCb = (unsigned char *)in + height * width + (height * width / 2);
483 for (i = 0; i < size * 2; i += 4) {
484 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
485 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
486 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
487 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
488 }
489 return;
490}
491
Hans Verkuild45b9b82008-09-04 03:33:43 -0300492static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300493{
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300494 s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300495 msleep(10);
496 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300497 msleep(600);
498 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300499 return;
500}
Dean Anderson38f993a2008-06-26 23:15:51 -0300501
502/* kickstarts the firmware loading. from probe
503 */
504static void s2255_timer(unsigned long user_data)
505{
506 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson85b85482010-04-08 23:51:17 -0300507 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300508 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
509 printk(KERN_ERR "s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300510 atomic_set(&data->fw_state, S2255_FW_FAILED);
511 /* wake up anything waiting for the firmware */
512 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300513 return;
514 }
515}
516
Dean Anderson38f993a2008-06-26 23:15:51 -0300517
518/* this loads the firmware asynchronously.
519 Originally this was done synchroously in probe.
520 But it is better to load it asynchronously here than block
521 inside the probe function. Blocking inside probe affects boot time.
522 FW loading is triggered by the timer in the probe function
523*/
524static void s2255_fwchunk_complete(struct urb *urb)
525{
526 struct s2255_fw *data = urb->context;
527 struct usb_device *udev = urb->dev;
528 int len;
Dean Anderson85b85482010-04-08 23:51:17 -0300529 dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
Dean Anderson38f993a2008-06-26 23:15:51 -0300530 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300531 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300532 atomic_set(&data->fw_state, S2255_FW_FAILED);
533 /* wake up anything waiting for the firmware */
534 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300535 return;
536 }
537 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300538 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300539 atomic_set(&data->fw_state, S2255_FW_FAILED);
540 /* wake up anything waiting for the firmware */
541 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300542 return;
543 }
544#define CHUNK_SIZE 512
545 /* all USB transfers must be done with continuous kernel memory.
546 can't allocate more than 128k in current linux kernel, so
547 upload the firmware in chunks
548 */
549 if (data->fw_loaded < data->fw_size) {
550 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
551 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
552
553 if (len < CHUNK_SIZE)
554 memset(data->pfw_data, 0, CHUNK_SIZE);
555
556 dprintk(100, "completed len %d, loaded %d \n", len,
557 data->fw_loaded);
558
559 memcpy(data->pfw_data,
560 (char *) data->fw->data + data->fw_loaded, len);
561
562 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
563 data->pfw_data, CHUNK_SIZE,
564 s2255_fwchunk_complete, data);
565 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
566 dev_err(&udev->dev, "failed submit URB\n");
567 atomic_set(&data->fw_state, S2255_FW_FAILED);
568 /* wake up anything waiting for the firmware */
569 wake_up(&data->wait_fw);
570 return;
571 }
572 data->fw_loaded += len;
573 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300574 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson85b85482010-04-08 23:51:17 -0300575 dprintk(100, "%s: firmware upload complete\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300576 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300577 return;
578
579}
580
Dean Andersonfe85ce92010-06-01 19:12:07 -0300581static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300582{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300583 struct s2255_dmaqueue *dma_q = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300584 struct s2255_buffer *buf;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300585 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300586 unsigned long flags = 0;
587 int rc = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300588 spin_lock_irqsave(&dev->slock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300589 if (list_empty(&dma_q->active)) {
590 dprintk(1, "No active queue to serve\n");
591 rc = -1;
592 goto unlock;
593 }
594 buf = list_entry(dma_q->active.next,
595 struct s2255_buffer, vb.queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300596 list_del(&buf->vb.queue);
597 do_gettimeofday(&buf->vb.ts);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300598 s2255_fillbuff(channel, buf, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300599 wake_up(&buf->vb.done);
Dean Anderson85b85482010-04-08 23:51:17 -0300600 dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
Dean Anderson38f993a2008-06-26 23:15:51 -0300601unlock:
602 spin_unlock_irqrestore(&dev->slock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300603 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300604}
605
Dean Anderson38f993a2008-06-26 23:15:51 -0300606static const struct s2255_fmt *format_by_fourcc(int fourcc)
607{
608 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300609 for (i = 0; i < ARRAY_SIZE(formats); i++) {
610 if (-1 == formats[i].fourcc)
611 continue;
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300612 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
613 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
614 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300615 if (formats[i].fourcc == fourcc)
616 return formats + i;
617 }
618 return NULL;
619}
620
Dean Anderson38f993a2008-06-26 23:15:51 -0300621/* video buffer vmalloc implementation based partly on VIVI driver which is
622 * Copyright (c) 2006 by
623 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
624 * Ted Walther <ted--a.t--enumera.com>
625 * John Sokol <sokol--a.t--videotechnology.com>
626 * http://v4l.videotechnology.com/
627 *
628 */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300629static void s2255_fillbuff(struct s2255_channel *channel,
630 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300631{
632 int pos = 0;
633 struct timeval ts;
634 const char *tmpbuf;
635 char *vbuf = videobuf_to_vmalloc(&buf->vb);
636 unsigned long last_frame;
637 struct s2255_framei *frm;
638
639 if (!vbuf)
640 return;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300641 last_frame = channel->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300642 if (last_frame != -1) {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300643 frm = &channel->buffer.frame[last_frame];
Dean Anderson38f993a2008-06-26 23:15:51 -0300644 tmpbuf =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300645 (const char *)channel->buffer.frame[last_frame].lpvbits;
Dean Anderson38f993a2008-06-26 23:15:51 -0300646 switch (buf->fmt->fourcc) {
647 case V4L2_PIX_FMT_YUYV:
648 case V4L2_PIX_FMT_UYVY:
649 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
650 vbuf, buf->vb.width,
651 buf->vb.height,
652 buf->fmt->fourcc);
653 break;
654 case V4L2_PIX_FMT_GREY:
655 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
656 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300657 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300658 case V4L2_PIX_FMT_MJPEG:
Dean Anderson14d96262008-08-25 13:58:55 -0300659 buf->vb.size = jpgsize;
660 memcpy(vbuf, tmpbuf, buf->vb.size);
661 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300662 case V4L2_PIX_FMT_YUV422P:
663 memcpy(vbuf, tmpbuf,
664 buf->vb.width * buf->vb.height * 2);
665 break;
666 default:
667 printk(KERN_DEBUG "s2255: unknown format?\n");
668 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300669 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300670 } else {
671 printk(KERN_ERR "s2255: =======no frame\n");
672 return;
673
674 }
675 dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
676 (unsigned long)vbuf, pos);
677 /* tell v4l buffer was filled */
678
Dean Andersonfe85ce92010-06-01 19:12:07 -0300679 buf->vb.field_count = channel->frame_count * 2;
Dean Anderson38f993a2008-06-26 23:15:51 -0300680 do_gettimeofday(&ts);
681 buf->vb.ts = ts;
682 buf->vb.state = VIDEOBUF_DONE;
683}
684
685
686/* ------------------------------------------------------------------
687 Videobuf operations
688 ------------------------------------------------------------------*/
689
690static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
691 unsigned int *size)
692{
693 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300694 struct s2255_channel *channel = fh->channel;
695 *size = channel->width * channel->height * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300696
697 if (0 == *count)
698 *count = S2255_DEF_BUFS;
699
Andreas Bombedab7e312010-03-21 16:02:45 -0300700 if (*size * *count > vid_limit * 1024 * 1024)
701 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300702
703 return 0;
704}
705
706static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
707{
708 dprintk(4, "%s\n", __func__);
709
Dean Anderson38f993a2008-06-26 23:15:51 -0300710 videobuf_vmalloc_free(&buf->vb);
711 buf->vb.state = VIDEOBUF_NEEDS_INIT;
712}
713
714static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
715 enum v4l2_field field)
716{
717 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300718 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300719 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
720 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300721 int w = channel->width;
722 int h = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300723 dprintk(4, "%s, field=%d\n", __func__, field);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300724 if (channel->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300725 return -EINVAL;
726
Dean Andersonfe85ce92010-06-01 19:12:07 -0300727 if ((w < norm_minw(&channel->vdev)) ||
728 (w > norm_maxw(&channel->vdev)) ||
729 (h < norm_minh(&channel->vdev)) ||
730 (h > norm_maxh(&channel->vdev))) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300731 dprintk(4, "invalid buffer prepare\n");
732 return -EINVAL;
733 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300734 buf->vb.size = w * h * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300735 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
736 dprintk(4, "invalid buffer prepare\n");
737 return -EINVAL;
738 }
739
Dean Andersonfe85ce92010-06-01 19:12:07 -0300740 buf->fmt = channel->fmt;
741 buf->vb.width = w;
742 buf->vb.height = h;
Dean Anderson38f993a2008-06-26 23:15:51 -0300743 buf->vb.field = field;
744
Dean Anderson38f993a2008-06-26 23:15:51 -0300745 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
746 rc = videobuf_iolock(vq, &buf->vb, NULL);
747 if (rc < 0)
748 goto fail;
749 }
750
751 buf->vb.state = VIDEOBUF_PREPARED;
752 return 0;
753fail:
754 free_buffer(vq, buf);
755 return rc;
756}
757
758static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
759{
760 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
761 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300762 struct s2255_channel *channel = fh->channel;
763 struct s2255_dmaqueue *vidq = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300764 dprintk(1, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300765 buf->vb.state = VIDEOBUF_QUEUED;
766 list_add_tail(&buf->vb.queue, &vidq->active);
767}
768
769static void buffer_release(struct videobuf_queue *vq,
770 struct videobuf_buffer *vb)
771{
772 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
773 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300774 dprintk(4, "%s %d\n", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -0300775 free_buffer(vq, buf);
776}
777
778static struct videobuf_queue_ops s2255_video_qops = {
779 .buf_setup = buffer_setup,
780 .buf_prepare = buffer_prepare,
781 .buf_queue = buffer_queue,
782 .buf_release = buffer_release,
783};
784
785
Dean Andersonfe85ce92010-06-01 19:12:07 -0300786static int res_get(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300787{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300788 struct s2255_channel *channel = fh->channel;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300789 /* is it free? */
790 if (channel->resources)
791 return 0; /* no, someone else uses it */
Dean Anderson38f993a2008-06-26 23:15:51 -0300792 /* it's free, grab it */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300793 channel->resources = 1;
794 fh->resources = 1;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300795 dprintk(1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300796 return 1;
797}
798
Dean Andersonfe85ce92010-06-01 19:12:07 -0300799static int res_locked(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300800{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300801 return fh->channel->resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300802}
803
Dean Andersonf78d92c2008-07-22 14:43:27 -0300804static int res_check(struct s2255_fh *fh)
805{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300806 return fh->resources;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300807}
808
809
Dean Andersonfe85ce92010-06-01 19:12:07 -0300810static void res_free(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300811{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300812 struct s2255_channel *channel = fh->channel;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300813 channel->resources = 0;
814 fh->resources = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300815 dprintk(1, "res: put\n");
816}
817
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300818static int vidioc_querymenu(struct file *file, void *priv,
819 struct v4l2_querymenu *qmenu)
820{
821 static const char *colorfilter[] = {
822 "Off",
823 "On",
824 NULL
825 };
826 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
827 int i;
828 const char **menu_items = colorfilter;
829 for (i = 0; i < qmenu->index && menu_items[i]; i++)
830 ; /* do nothing (from v4l2-common.c) */
831 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
832 return -EINVAL;
833 strlcpy(qmenu->name, menu_items[qmenu->index],
834 sizeof(qmenu->name));
835 return 0;
836 }
837 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
838}
839
Dean Anderson38f993a2008-06-26 23:15:51 -0300840static int vidioc_querycap(struct file *file, void *priv,
841 struct v4l2_capability *cap)
842{
843 struct s2255_fh *fh = file->private_data;
844 struct s2255_dev *dev = fh->dev;
845 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
846 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300847 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Dean Anderson38f993a2008-06-26 23:15:51 -0300848 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
849 return 0;
850}
851
852static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
853 struct v4l2_fmtdesc *f)
854{
855 int index = 0;
856 if (f)
857 index = f->index;
858
859 if (index >= ARRAY_SIZE(formats))
860 return -EINVAL;
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300861 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
862 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
863 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300864 dprintk(4, "name %s\n", formats[index].name);
865 strlcpy(f->description, formats[index].name, sizeof(f->description));
866 f->pixelformat = formats[index].fourcc;
867 return 0;
868}
869
870static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
871 struct v4l2_format *f)
872{
873 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300874 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300875
Dean Andersonfe85ce92010-06-01 19:12:07 -0300876 f->fmt.pix.width = channel->width;
877 f->fmt.pix.height = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300878 f->fmt.pix.field = fh->vb_vidq.field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300879 f->fmt.pix.pixelformat = channel->fmt->fourcc;
880 f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300881 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300882 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300883}
884
885static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
886 struct v4l2_format *f)
887{
888 const struct s2255_fmt *fmt;
889 enum v4l2_field field;
890 int b_any_field = 0;
891 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300892 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300893 int is_ntsc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300894 is_ntsc =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300895 (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300896
897 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
898
899 if (fmt == NULL)
900 return -EINVAL;
901
902 field = f->fmt.pix.field;
903 if (field == V4L2_FIELD_ANY)
904 b_any_field = 1;
905
Dean Anderson85b85482010-04-08 23:51:17 -0300906 dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
907 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300908 if (is_ntsc) {
909 /* NTSC */
910 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
911 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
912 if (b_any_field) {
913 field = V4L2_FIELD_SEQ_TB;
914 } else if (!((field == V4L2_FIELD_INTERLACED) ||
915 (field == V4L2_FIELD_SEQ_TB) ||
916 (field == V4L2_FIELD_INTERLACED_TB))) {
917 dprintk(1, "unsupported field setting\n");
918 return -EINVAL;
919 }
920 } else {
921 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
922 if (b_any_field) {
923 field = V4L2_FIELD_TOP;
924 } else if (!((field == V4L2_FIELD_TOP) ||
925 (field == V4L2_FIELD_BOTTOM))) {
926 dprintk(1, "unsupported field setting\n");
927 return -EINVAL;
928 }
929
930 }
931 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
932 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
933 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
934 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
935 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
936 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
937 else
938 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
939 } else {
940 /* PAL */
941 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
942 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
943 if (b_any_field) {
944 field = V4L2_FIELD_SEQ_TB;
945 } else if (!((field == V4L2_FIELD_INTERLACED) ||
946 (field == V4L2_FIELD_SEQ_TB) ||
947 (field == V4L2_FIELD_INTERLACED_TB))) {
948 dprintk(1, "unsupported field setting\n");
949 return -EINVAL;
950 }
951 } else {
952 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
953 if (b_any_field) {
954 field = V4L2_FIELD_TOP;
955 } else if (!((field == V4L2_FIELD_TOP) ||
956 (field == V4L2_FIELD_BOTTOM))) {
957 dprintk(1, "unsupported field setting\n");
958 return -EINVAL;
959 }
960 }
961 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300962 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
963 field = V4L2_FIELD_SEQ_TB;
964 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300965 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
966 field = V4L2_FIELD_TOP;
967 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300968 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
969 field = V4L2_FIELD_TOP;
970 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300971 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
972 field = V4L2_FIELD_TOP;
973 }
974 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300975 f->fmt.pix.field = field;
976 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
977 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson85b85482010-04-08 23:51:17 -0300978 dprintk(50, "%s: set width %d height %d field %d\n", __func__,
979 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300980 return 0;
981}
982
983static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
984 struct v4l2_format *f)
985{
986 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300987 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300988 const struct s2255_fmt *fmt;
989 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300990 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300991 int ret;
992 int norm;
993
994 ret = vidioc_try_fmt_vid_cap(file, fh, f);
995
996 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300997 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300998
999 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1000
1001 if (fmt == NULL)
1002 return -EINVAL;
1003
1004 mutex_lock(&q->vb_lock);
1005
1006 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1007 dprintk(1, "queue busy\n");
1008 ret = -EBUSY;
1009 goto out_s_fmt;
1010 }
1011
Dean Andersonfe85ce92010-06-01 19:12:07 -03001012 if (res_locked(fh)) {
Dean Anderson85b85482010-04-08 23:51:17 -03001013 dprintk(1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001014 ret = -EBUSY;
1015 goto out_s_fmt;
1016 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001017 mode = channel->mode;
1018 channel->fmt = fmt;
1019 channel->width = f->fmt.pix.width;
1020 channel->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -03001021 fh->vb_vidq.field = f->fmt.pix.field;
1022 fh->type = f->type;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001023 norm = norm_minw(&channel->vdev);
1024 if (channel->width > norm_minw(&channel->vdev)) {
1025 if (channel->height > norm_minh(&channel->vdev)) {
1026 if (channel->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -03001027 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001028 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -03001029 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001030 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -03001031 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001032 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001033
1034 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001035 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001036 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001037 /* color mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001038 switch (channel->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001039 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001040 mode.color &= ~MASK_COLOR;
1041 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001042 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001043 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -03001044 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001045 mode.color &= ~MASK_COLOR;
1046 mode.color |= COLOR_JPG;
1047 mode.color |= (channel->jc.quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001048 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001049 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001050 mode.color &= ~MASK_COLOR;
1051 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001052 break;
1053 case V4L2_PIX_FMT_YUYV:
1054 case V4L2_PIX_FMT_UYVY:
1055 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001056 mode.color &= ~MASK_COLOR;
1057 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001058 break;
1059 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001060 if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
1061 mode.restart = 1;
1062 else if (mode.scale != channel->mode.scale)
1063 mode.restart = 1;
1064 else if (mode.format != channel->mode.format)
1065 mode.restart = 1;
1066 channel->mode = mode;
1067 (void) s2255_set_mode(channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001068 ret = 0;
1069out_s_fmt:
1070 mutex_unlock(&q->vb_lock);
1071 return ret;
1072}
1073
1074static int vidioc_reqbufs(struct file *file, void *priv,
1075 struct v4l2_requestbuffers *p)
1076{
1077 int rc;
1078 struct s2255_fh *fh = priv;
1079 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1080 return rc;
1081}
1082
1083static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1084{
1085 int rc;
1086 struct s2255_fh *fh = priv;
1087 rc = videobuf_querybuf(&fh->vb_vidq, p);
1088 return rc;
1089}
1090
1091static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1092{
1093 int rc;
1094 struct s2255_fh *fh = priv;
1095 rc = videobuf_qbuf(&fh->vb_vidq, p);
1096 return rc;
1097}
1098
1099static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1100{
1101 int rc;
1102 struct s2255_fh *fh = priv;
1103 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1104 return rc;
1105}
1106
Dean Anderson38f993a2008-06-26 23:15:51 -03001107/* write to the configuration pipe, synchronously */
1108static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1109 int size)
1110{
1111 int pipe;
1112 int done;
1113 long retval = -1;
1114 if (udev) {
1115 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1116 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1117 }
1118 return retval;
1119}
1120
1121static u32 get_transfer_size(struct s2255_mode *mode)
1122{
1123 int linesPerFrame = LINE_SZ_DEF;
1124 int pixelsPerLine = NUM_LINES_DEF;
1125 u32 outImageSize;
1126 u32 usbInSize;
1127 unsigned int mask_mult;
1128
1129 if (mode == NULL)
1130 return 0;
1131
1132 if (mode->format == FORMAT_NTSC) {
1133 switch (mode->scale) {
1134 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001135 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001136 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1137 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1138 break;
1139 case SCALE_2CIFS:
1140 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1141 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1142 break;
1143 case SCALE_1CIFS:
1144 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1145 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1146 break;
1147 default:
1148 break;
1149 }
1150 } else if (mode->format == FORMAT_PAL) {
1151 switch (mode->scale) {
1152 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001153 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001154 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1155 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1156 break;
1157 case SCALE_2CIFS:
1158 linesPerFrame = NUM_LINES_2CIFS_PAL;
1159 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1160 break;
1161 case SCALE_1CIFS:
1162 linesPerFrame = NUM_LINES_1CIFS_PAL;
1163 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1164 break;
1165 default:
1166 break;
1167 }
1168 }
1169 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001170 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001171 /* 2 bytes/pixel if not monochrome */
1172 outImageSize *= 2;
1173 }
1174
1175 /* total bytes to send including prefix and 4K padding;
1176 must be a multiple of USB_READ_SIZE */
1177 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1178 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1179 /* if size not a multiple of USB_READ_SIZE */
1180 if (usbInSize & ~mask_mult)
1181 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1182 return usbInSize;
1183}
1184
Dean Anderson85b85482010-04-08 23:51:17 -03001185static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001186{
1187 struct device *dev = &sdev->udev->dev;
1188 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001189 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1190 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001191 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001192 dev_info(dev, "------------------------------------------------\n");
1193}
1194
1195/*
1196 * set mode is the function which controls the DSP.
1197 * the restart parameter in struct s2255_mode should be set whenever
1198 * the image size could change via color format, video system or image
1199 * size.
1200 * When the restart parameter is set, we sleep for ONE frame to allow the
1201 * DSP time to get the new frame
1202 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001203static int s2255_set_mode(struct s2255_channel *channel,
Dean Anderson38f993a2008-06-26 23:15:51 -03001204 struct s2255_mode *mode)
1205{
1206 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001207 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001208 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001209 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001210 chn_rev = G_chnmap[channel->idx];
1211 dprintk(3, "%s channel: %d\n", __func__, channel->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001212 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001213 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1214 mode->color &= ~MASK_COLOR;
1215 mode->color |= COLOR_JPG;
1216 mode->color &= ~MASK_JPG_QUALITY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001217 mode->color |= (channel->jc.quality << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001218 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001219 /* save the mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001220 channel->mode = *mode;
1221 channel->req_image_size = get_transfer_size(mode);
1222 dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001223 buffer = kzalloc(512, GFP_KERNEL);
1224 if (buffer == NULL) {
1225 dev_err(&dev->udev->dev, "out of mem\n");
1226 return -ENOMEM;
1227 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001228 /* set the mode */
1229 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001230 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001231 buffer[2] = CMD_SET_MODE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001232 memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
1233 channel->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001234 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1235 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001236 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001237 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001238 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001239 if (mode->restart) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001240 wait_event_timeout(channel->wait_setmode,
1241 (channel->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001242 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001243 if (channel->setmode_ready != 1) {
Dean Anderson14d96262008-08-25 13:58:55 -03001244 printk(KERN_DEBUG "s2255: no set mode response\n");
1245 res = -EFAULT;
1246 }
1247 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001248 /* clear the restart flag */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001249 channel->mode.restart = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001250 dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001251 return res;
1252}
1253
Dean Andersonfe85ce92010-06-01 19:12:07 -03001254static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001255{
1256 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001257 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001258 u32 chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001259 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001260 chn_rev = G_chnmap[channel->idx];
1261 dprintk(4, "%s chan %d\n", __func__, channel->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001262 buffer = kzalloc(512, GFP_KERNEL);
1263 if (buffer == NULL) {
1264 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001265 return -ENOMEM;
1266 }
1267 /* form the get vid status command */
1268 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001269 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001270 buffer[2] = CMD_STATUS;
1271 *pstatus = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001272 channel->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001273 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1274 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001275 wait_event_timeout(channel->wait_vidstatus,
1276 (channel->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001277 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001278 if (channel->vidstatus_ready != 1) {
Dean Anderson4de39f52010-03-03 19:39:19 -03001279 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1280 res = -EFAULT;
1281 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001282 *pstatus = channel->vidstatus;
Dean Anderson4de39f52010-03-03 19:39:19 -03001283 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03001284 return res;
1285}
1286
Dean Anderson38f993a2008-06-26 23:15:51 -03001287static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1288{
1289 int res;
1290 struct s2255_fh *fh = priv;
1291 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001292 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001293 int j;
1294 dprintk(4, "%s\n", __func__);
1295 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1296 dev_err(&dev->udev->dev, "invalid fh type0\n");
1297 return -EINVAL;
1298 }
1299 if (i != fh->type) {
1300 dev_err(&dev->udev->dev, "invalid fh type1\n");
1301 return -EINVAL;
1302 }
1303
Dean Andersonfe85ce92010-06-01 19:12:07 -03001304 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001305 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001306 return -EBUSY;
1307 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001308 channel->last_frame = -1;
1309 channel->bad_payload = 0;
1310 channel->cur_frame = 0;
1311 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001312 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001313 channel->buffer.frame[j].ulState = S2255_READ_IDLE;
1314 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001315 }
1316 res = videobuf_streamon(&fh->vb_vidq);
1317 if (res == 0) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001318 s2255_start_acquire(channel);
1319 channel->b_acquire = 1;
1320 } else
1321 res_free(fh);
1322
Dean Anderson38f993a2008-06-26 23:15:51 -03001323 return res;
1324}
1325
1326static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1327{
Dean Anderson38f993a2008-06-26 23:15:51 -03001328 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001329 dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001330 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1331 printk(KERN_ERR "invalid fh type0\n");
1332 return -EINVAL;
1333 }
1334 if (i != fh->type) {
1335 printk(KERN_ERR "invalid type i\n");
1336 return -EINVAL;
1337 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001338 s2255_stop_acquire(fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001339 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001340 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001341 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001342}
1343
1344static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1345{
1346 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001347 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001348 struct videobuf_queue *q = &fh->vb_vidq;
1349 int ret = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001350 mutex_lock(&q->vb_lock);
1351 if (videobuf_queue_is_busy(q)) {
1352 dprintk(1, "queue busy\n");
1353 ret = -EBUSY;
1354 goto out_s_std;
1355 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001356 if (res_locked(fh)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001357 dprintk(1, "can't change standard after started\n");
1358 ret = -EBUSY;
1359 goto out_s_std;
1360 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001361 mode = fh->channel->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001362 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001363 dprintk(4, "%s NTSC\n", __func__);
1364 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001365 if (mode.format != FORMAT_NTSC) {
1366 mode.restart = 1;
1367 mode.format = FORMAT_NTSC;
1368 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001369 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001370 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001371 dprintk(4, "%s PAL\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001372 if (mode.format != FORMAT_PAL) {
1373 mode.restart = 1;
1374 mode.format = FORMAT_PAL;
1375 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001376 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001377 } else {
1378 ret = -EINVAL;
1379 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001380 if (mode.restart)
1381 s2255_set_mode(fh->channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001382out_s_std:
1383 mutex_unlock(&q->vb_lock);
1384 return ret;
1385}
1386
1387/* Sensoray 2255 is a multiple channel capture device.
1388 It does not have a "crossbar" of inputs.
1389 We use one V4L device per channel. The user must
1390 be aware that certain combinations are not allowed.
1391 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1392 at once in color(you can do full fps on 4 channels with greyscale.
1393*/
1394static int vidioc_enum_input(struct file *file, void *priv,
1395 struct v4l2_input *inp)
1396{
Dean Anderson4de39f52010-03-03 19:39:19 -03001397 struct s2255_fh *fh = priv;
1398 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001399 struct s2255_channel *channel = fh->channel;
Dean Anderson4de39f52010-03-03 19:39:19 -03001400 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001401 if (inp->index != 0)
1402 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001403 inp->type = V4L2_INPUT_TYPE_CAMERA;
1404 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001405 inp->status = 0;
1406 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1407 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001408 rc = s2255_cmd_status(fh->channel, &status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001409 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1410 if (rc == 0)
1411 inp->status = (status & 0x01) ? 0
1412 : V4L2_IN_ST_NO_SIGNAL;
1413 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001414 switch (dev->pid) {
1415 case 0x2255:
1416 default:
1417 strlcpy(inp->name, "Composite", sizeof(inp->name));
1418 break;
1419 case 0x2257:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001420 strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001421 sizeof(inp->name));
1422 break;
1423 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001424 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001425}
1426
1427static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1428{
1429 *i = 0;
1430 return 0;
1431}
1432static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1433{
1434 if (i > 0)
1435 return -EINVAL;
1436 return 0;
1437}
1438
1439/* --- controls ---------------------------------------------- */
1440static int vidioc_queryctrl(struct file *file, void *priv,
1441 struct v4l2_queryctrl *qc)
1442{
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001443 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001444 struct s2255_channel *channel = fh->channel;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001445 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001446 switch (qc->id) {
1447 case V4L2_CID_BRIGHTNESS:
1448 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1449 break;
1450 case V4L2_CID_CONTRAST:
1451 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1452 break;
1453 case V4L2_CID_SATURATION:
1454 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1455 break;
1456 case V4L2_CID_HUE:
1457 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1458 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001459 case V4L2_CID_PRIVATE_COLORFILTER:
1460 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1461 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001462 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001463 return -EINVAL;
1464 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1465 qc->type = V4L2_CTRL_TYPE_MENU;
1466 qc->minimum = 0;
1467 qc->maximum = 1;
1468 qc->step = 1;
1469 qc->default_value = 1;
1470 qc->flags = 0;
1471 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001472 default:
1473 return -EINVAL;
1474 }
1475 dprintk(4, "%s, id %d\n", __func__, qc->id);
1476 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001477}
1478
1479static int vidioc_g_ctrl(struct file *file, void *priv,
1480 struct v4l2_control *ctrl)
1481{
Dean Anderson2e70db92010-03-05 14:29:09 -03001482 struct s2255_fh *fh = priv;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001483 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001484 struct s2255_channel *channel = fh->channel;
Dean Anderson2e70db92010-03-05 14:29:09 -03001485 switch (ctrl->id) {
1486 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001487 ctrl->value = channel->mode.bright;
Dean Anderson2e70db92010-03-05 14:29:09 -03001488 break;
1489 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001490 ctrl->value = channel->mode.contrast;
Dean Anderson2e70db92010-03-05 14:29:09 -03001491 break;
1492 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001493 ctrl->value = channel->mode.saturation;
Dean Anderson2e70db92010-03-05 14:29:09 -03001494 break;
1495 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001496 ctrl->value = channel->mode.hue;
Dean Anderson2e70db92010-03-05 14:29:09 -03001497 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001498 case V4L2_CID_PRIVATE_COLORFILTER:
1499 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1500 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001501 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001502 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001503 ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001504 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001505 default:
1506 return -EINVAL;
1507 }
1508 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1509 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001510}
1511
1512static int vidioc_s_ctrl(struct file *file, void *priv,
1513 struct v4l2_control *ctrl)
1514{
Dean Anderson38f993a2008-06-26 23:15:51 -03001515 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001516 struct s2255_channel *channel = fh->channel;
1517 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
1518 struct s2255_mode mode;
1519 mode = channel->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001520 dprintk(4, "%s\n", __func__);
1521 /* update the mode to the corresponding value */
1522 switch (ctrl->id) {
1523 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001524 mode.bright = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001525 break;
1526 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001527 mode.contrast = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001528 break;
1529 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001530 mode.hue = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001531 break;
1532 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001533 mode.saturation = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001534 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001535 case V4L2_CID_PRIVATE_COLORFILTER:
1536 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1537 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001538 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001539 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001540 mode.color &= ~MASK_INPUT_TYPE;
1541 mode.color |= ((ctrl->value ? 0 : 1) << 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001542 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001543 default:
1544 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001545 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001546 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001547 /* set mode here. Note: stream does not need restarted.
1548 some V4L programs restart stream unnecessarily
1549 after a s_crtl.
1550 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001551 s2255_set_mode(fh->channel, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001552 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001553}
1554
Dean Anderson22b88d42008-08-29 15:33:19 -03001555static int vidioc_g_jpegcomp(struct file *file, void *priv,
1556 struct v4l2_jpegcompression *jc)
1557{
1558 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001559 struct s2255_channel *channel = fh->channel;
1560 *jc = channel->jc;
Dean Anderson85b85482010-04-08 23:51:17 -03001561 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001562 return 0;
1563}
1564
1565static int vidioc_s_jpegcomp(struct file *file, void *priv,
1566 struct v4l2_jpegcompression *jc)
1567{
1568 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001569 struct s2255_channel *channel = fh->channel;
Dean Anderson22b88d42008-08-29 15:33:19 -03001570 if (jc->quality < 0 || jc->quality > 100)
1571 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001572 channel->jc.quality = jc->quality;
Dean Anderson85b85482010-04-08 23:51:17 -03001573 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001574 return 0;
1575}
Dean Anderson7d853532009-05-15 14:32:04 -03001576
1577static int vidioc_g_parm(struct file *file, void *priv,
1578 struct v4l2_streamparm *sp)
1579{
1580 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001581 __u32 def_num, def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001582 struct s2255_channel *channel = fh->channel;
Dean Anderson7d853532009-05-15 14:32:04 -03001583 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1584 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001585 memset(sp, 0, sizeof(struct v4l2_streamparm));
1586 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001587 sp->parm.capture.capturemode = channel->cap_parm.capturemode;
1588 def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1589 def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001590 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001591 switch (channel->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001592 default:
1593 case FDEC_1:
1594 sp->parm.capture.timeperframe.numerator = def_num;
1595 break;
1596 case FDEC_2:
1597 sp->parm.capture.timeperframe.numerator = def_num * 2;
1598 break;
1599 case FDEC_3:
1600 sp->parm.capture.timeperframe.numerator = def_num * 3;
1601 break;
1602 case FDEC_5:
1603 sp->parm.capture.timeperframe.numerator = def_num * 5;
1604 break;
1605 }
1606 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1607 sp->parm.capture.capturemode,
1608 sp->parm.capture.timeperframe.numerator,
1609 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001610 return 0;
1611}
1612
1613static int vidioc_s_parm(struct file *file, void *priv,
1614 struct v4l2_streamparm *sp)
1615{
1616 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001617 struct s2255_channel *channel = fh->channel;
1618 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001619 int fdec = FDEC_1;
1620 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001621 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1622 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001623 mode = channel->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001624 /* high quality capture mode requires a stream restart */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001625 if (channel->cap_parm.capturemode
1626 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001627 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001628 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1629 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001630 if (def_dem != sp->parm.capture.timeperframe.denominator)
1631 sp->parm.capture.timeperframe.numerator = def_num;
1632 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1633 sp->parm.capture.timeperframe.numerator = def_num;
1634 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1635 sp->parm.capture.timeperframe.numerator = def_num * 2;
1636 fdec = FDEC_2;
1637 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1638 sp->parm.capture.timeperframe.numerator = def_num * 3;
1639 fdec = FDEC_3;
1640 } else {
1641 sp->parm.capture.timeperframe.numerator = def_num * 5;
1642 fdec = FDEC_5;
1643 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001644 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001645 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001646 s2255_set_mode(channel, &mode);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001647 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1648 __func__,
1649 sp->parm.capture.capturemode,
1650 sp->parm.capture.timeperframe.numerator,
1651 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001652 return 0;
1653}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001654
1655static int vidioc_enum_frameintervals(struct file *file, void *priv,
1656 struct v4l2_frmivalenum *fe)
1657{
1658 int is_ntsc = 0;
1659#define NUM_FRAME_ENUMS 4
1660 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
1661 if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
1662 return -EINVAL;
1663 switch (fe->width) {
1664 case 640:
1665 if (fe->height != 240 && fe->height != 480)
1666 return -EINVAL;
1667 is_ntsc = 1;
1668 break;
1669 case 320:
1670 if (fe->height != 240)
1671 return -EINVAL;
1672 is_ntsc = 1;
1673 break;
1674 case 704:
1675 if (fe->height != 288 && fe->height != 576)
1676 return -EINVAL;
1677 break;
1678 case 352:
1679 if (fe->height != 288)
1680 return -EINVAL;
1681 break;
1682 default:
1683 return -EINVAL;
1684 }
1685 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1686 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1687 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1688 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1689 fe->discrete.denominator);
1690 return 0;
1691}
1692
Hans Verkuilbec43662008-12-30 06:58:20 -03001693static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001694{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001695 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001696 struct s2255_channel *channel = video_drvdata(file);
1697 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001698 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001699 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001700 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001701 dprintk(1, "s2255: open called (dev=%s)\n",
1702 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001703 /*
1704 * open lock necessary to prevent multiple instances
1705 * of v4l-conf (or other programs) from simultaneously
1706 * reloading firmware.
1707 */
Dean Anderson38f993a2008-06-26 23:15:51 -03001708 mutex_lock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001709 state = atomic_read(&dev->fw_data->fw_state);
1710 switch (state) {
1711 case S2255_FW_DISCONNECTING:
1712 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001713 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001714 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001715 s2255_dev_err(&dev->udev->dev,
1716 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001717 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001718 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 Anderson38f993a2008-06-26 23:15:51 -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_NOTLOADED:
1728 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001729 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1730 driver loaded and then device immediately opened */
1731 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1732 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001733 ((atomic_read(&dev->fw_data->fw_state)
1734 == S2255_FW_SUCCESS) ||
1735 (atomic_read(&dev->fw_data->fw_state)
1736 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001737 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001738 /* state may have changed, re-read */
1739 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001740 break;
1741 case S2255_FW_SUCCESS:
1742 default:
1743 break;
1744 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001745 /* state may have changed in above switch statement */
1746 switch (state) {
1747 case S2255_FW_SUCCESS:
1748 break;
1749 case S2255_FW_FAILED:
1750 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Andersoneb78dee2010-04-12 15:05:37 -03001751 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001752 return -ENODEV;
1753 case S2255_FW_DISCONNECTING:
1754 printk(KERN_INFO "%s: disconnecting\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001755 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001756 return -ENODEV;
1757 case S2255_FW_LOADED_DSPWAIT:
1758 case S2255_FW_NOTLOADED:
1759 printk(KERN_INFO "%s: firmware not loaded yet"
1760 "please try again later\n",
1761 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001762 /*
1763 * Timeout on firmware load means device unusable.
1764 * Set firmware failure state.
1765 * On next s2255_open the firmware will be reloaded.
1766 */
1767 atomic_set(&dev->fw_data->fw_state,
1768 S2255_FW_FAILED);
1769 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001770 return -EAGAIN;
1771 default:
1772 printk(KERN_INFO "%s: unknown state\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001773 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001774 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001775 }
Dean Andersoneb78dee2010-04-12 15:05:37 -03001776 mutex_unlock(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001777 /* allocate + initialize per filehandle data */
1778 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001779 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001780 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03001781 file->private_data = fh;
1782 fh->dev = dev;
1783 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001784 fh->channel = channel;
1785 if (!channel->configured) {
1786 /* configure channel to default state */
1787 channel->fmt = &formats[0];
1788 s2255_set_mode(channel, &channel->mode);
1789 channel->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001790 }
Dean Anderson85b85482010-04-08 23:51:17 -03001791 dprintk(1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001792 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson85b85482010-04-08 23:51:17 -03001793 dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001794 (unsigned long)fh, (unsigned long)dev,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001795 (unsigned long)&channel->vidq);
Dean Anderson85b85482010-04-08 23:51:17 -03001796 dprintk(4, "%s: list_empty active=%d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001797 list_empty(&channel->vidq.active));
Dean Anderson38f993a2008-06-26 23:15:51 -03001798 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1799 NULL, &dev->slock,
1800 fh->type,
1801 V4L2_FIELD_INTERLACED,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001802 sizeof(struct s2255_buffer),
1803 fh, vdev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001804 return 0;
1805}
1806
1807
1808static unsigned int s2255_poll(struct file *file,
1809 struct poll_table_struct *wait)
1810{
1811 struct s2255_fh *fh = file->private_data;
1812 int rc;
1813 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001814 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1815 return POLLERR;
Dean Anderson38f993a2008-06-26 23:15:51 -03001816 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
1817 return rc;
1818}
1819
Dean Andersond62e85a2010-04-09 19:54:26 -03001820static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001821{
Dean Anderson38f993a2008-06-26 23:15:51 -03001822 /* board shutdown stops the read pipe if it is running */
1823 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001824 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001825 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001826 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001827 usb_kill_urb(dev->fw_data->fw_urb);
1828 usb_free_urb(dev->fw_data->fw_urb);
1829 dev->fw_data->fw_urb = NULL;
1830 }
Dean Andersonf78d92c2008-07-22 14:43:27 -03001831 if (dev->fw_data->fw)
1832 release_firmware(dev->fw_data->fw);
1833 kfree(dev->fw_data->pfw_data);
1834 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001835 /* reset the DSP so firmware can be reloaded next time */
1836 s2255_reset_dsppower(dev);
1837 mutex_destroy(&dev->open_lock);
1838 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001839 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001840 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001841 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001842 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001843}
1844
Dean Andersonff7e22d2010-04-08 23:38:07 -03001845static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001846{
1847 struct s2255_fh *fh = file->private_data;
1848 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001849 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001850 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001851 if (!dev)
1852 return -ENODEV;
Dean Andersonf78d92c2008-07-22 14:43:27 -03001853 /* turn off stream */
1854 if (res_check(fh)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001855 if (channel->b_acquire)
1856 s2255_stop_acquire(fh->channel);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001857 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001858 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001859 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001860 videobuf_mmap_free(&fh->vb_vidq);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001861 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001862 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001863 return 0;
1864}
1865
1866static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1867{
1868 struct s2255_fh *fh = file->private_data;
1869 int ret;
1870
1871 if (!fh)
1872 return -ENODEV;
Dean Anderson85b85482010-04-08 23:51:17 -03001873 dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Dean Anderson38f993a2008-06-26 23:15:51 -03001874 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
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;
2030 cc = pdword[1];
2031 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];
Dean Anderson14d96262008-08-25 13:58:55 -03002039 payload = 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;
2046 channel->jpg_size = 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;
2052 if (pdword[1] >= MAX_CHANNELS)
2053 break;
2054 cc = G_chnmap[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:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002077 channel->vidstatus = pdword[3];
2078 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",
2081 pdword[3], cc);
2082 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);
2541 mutex_init(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002542 /* grab usb_device and save it */
2543 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2544 if (dev->udev == NULL) {
2545 dev_err(&interface->dev, "null usb device\n");
2546 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002547 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002548 }
Dean Andersond62e85a2010-04-09 19:54:26 -03002549 dprintk(1, "dev: %p, udev %p interface %p\n", dev,
Dean Anderson38f993a2008-06-26 23:15:51 -03002550 dev->udev, interface);
2551 dev->interface = interface;
2552 /* set up the endpoint information */
2553 iface_desc = interface->cur_altsetting;
2554 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2555 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2556 endpoint = &iface_desc->endpoint[i].desc;
2557 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2558 /* we found the bulk in endpoint */
2559 dev->read_endpoint = endpoint->bEndpointAddress;
2560 }
2561 }
2562
2563 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002564 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002565 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002566 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002567 init_timer(&dev->timer);
2568 dev->timer.function = s2255_timer;
2569 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002570 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002571 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002572 struct s2255_channel *channel = &dev->channel[i];
2573 dev->channel[i].idx = i;
2574 init_waitqueue_head(&channel->wait_setmode);
2575 init_waitqueue_head(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002576 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002577
2578 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002579 if (!dev->fw_data->fw_urb) {
2580 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002581 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002582 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002583
Dean Anderson38f993a2008-06-26 23:15:51 -03002584 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2585 if (!dev->fw_data->pfw_data) {
2586 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002587 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002588 }
2589 /* load the first chunk */
2590 if (request_firmware(&dev->fw_data->fw,
2591 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2592 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002593 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002594 }
Dean Anderson14d96262008-08-25 13:58:55 -03002595 /* check the firmware is valid */
2596 fw_size = dev->fw_data->fw->size;
2597 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002598
Dean Anderson14d96262008-08-25 13:58:55 -03002599 if (*pdata != S2255_FW_MARKER) {
2600 printk(KERN_INFO "Firmware invalid.\n");
2601 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002602 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002603 } else {
2604 /* make sure firmware is the latest */
2605 __le32 *pRel;
2606 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2607 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dean Anderson4de39f52010-03-03 19:39:19 -03002608 dev->dsp_fw_ver = *pRel;
2609 if (*pRel < S2255_CUR_DSP_FWVER)
2610 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002611 if (dev->pid == 0x2257 && *pRel < 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);
2642 mutex_destroy(&dev->open_lock);
2643 mutex_destroy(&dev->lock);
2644errorFWDATA1:
2645 kfree(dev);
2646 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002647 return retval;
2648}
2649
2650/* disconnect routine. when board is removed physically or with rmmod */
2651static void s2255_disconnect(struct usb_interface *interface)
2652{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002653 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002654 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002655 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002656 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002657 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002658 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002659 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002660 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002661 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002662 for (i = 0; i < channels; i++)
2663 video_unregister_device(&dev->channel[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002664 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002665 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2666 wake_up(&dev->fw_data->wait_fw);
2667 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002668 dev->channel[i].setmode_ready = 1;
2669 wake_up(&dev->channel[i].wait_setmode);
2670 dev->channel[i].vidstatus_ready = 1;
2671 wake_up(&dev->channel[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002672 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002673 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002674 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002675 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002676}
2677
2678static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002679 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002680 .probe = s2255_probe,
2681 .disconnect = s2255_disconnect,
2682 .id_table = s2255_table,
2683};
2684
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002685module_usb_driver(s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002686
2687MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2688MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2689MODULE_LICENSE("GPL");
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03002690MODULE_VERSION(S2255_VERSION);