blob: ea974fadb5e236504fc6c45cef5591017e17ac11 [file] [log] [blame]
Dean Anderson38f993a2008-06-26 23:15:51 -03001/*
2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
3 *
Dean Anderson4de39f52010-03-03 19:39:19 -03004 * Copyright (C) 2007-2010 by Sensoray Company Inc.
Dean Anderson38f993a2008-06-26 23:15:51 -03005 * Dean Anderson
6 *
7 * Some video buffer code based on vivi driver:
8 *
9 * Sensoray 2255 device supports 4 simultaneous channels.
10 * The channels are not "crossbar" inputs, they are physically
11 * attached to separate video decoders.
12 *
13 * Because of USB2.0 bandwidth limitations. There is only a
14 * certain amount of data which may be transferred at one time.
15 *
16 * Example maximum bandwidth utilization:
17 *
18 * -full size, color mode YUYV or YUV422P: 2 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030019 * -full or half size Grey scale: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030020 * -half size, color mode YUYV or YUV422P: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030021 * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
22 * at once.
Dean Anderson38f993a2008-06-26 23:15:51 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * (at your option) any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 */
38
39#include <linux/module.h>
40#include <linux/firmware.h>
41#include <linux/kernel.h>
42#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090043#include <linux/slab.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030044#include <linux/videodev2.h>
Hans Verkuilfeb75f02008-07-27 06:30:21 -030045#include <linux/mm.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030046#include <media/videobuf-vmalloc.h>
47#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030048#include <media/v4l2-device.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030049#include <media/v4l2-ioctl.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030050#include <linux/vmalloc.h>
51#include <linux/usb.h>
52
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -030053#define S2255_VERSION "1.22.1"
Dean Anderson38f993a2008-06-26 23:15:51 -030054#define FIRMWARE_FILE_NAME "f2255usb.bin"
55
Dean Anderson22b88d42008-08-29 15:33:19 -030056/* default JPEG quality */
57#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030058/* vendor request in */
59#define S2255_VR_IN 0
60/* vendor request out */
61#define S2255_VR_OUT 1
62/* firmware query */
63#define S2255_VR_FW 0x30
64/* USB endpoint number for configuring the device */
65#define S2255_CONFIG_EP 2
66/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030067#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030068/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030069#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson38f993a2008-06-26 23:15:51 -030070#define S2255_DEF_BUFS 16
Dean Anderson14d96262008-08-25 13:58:55 -030071#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030072#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030073#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
74#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
75#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
76#define S2255_RESPONSE_FW cpu_to_le32(0x10)
77#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030078#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030079#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030080#define SYS_FRAMES 4
81/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030082#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
83#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030084#define LINE_SZ_4CIFS_NTSC 640
85#define LINE_SZ_2CIFS_NTSC 640
86#define LINE_SZ_1CIFS_NTSC 320
87#define LINE_SZ_4CIFS_PAL 704
88#define LINE_SZ_2CIFS_PAL 704
89#define LINE_SZ_1CIFS_PAL 352
90#define NUM_LINES_4CIFS_NTSC 240
91#define NUM_LINES_2CIFS_NTSC 240
92#define NUM_LINES_1CIFS_NTSC 240
93#define NUM_LINES_4CIFS_PAL 288
94#define NUM_LINES_2CIFS_PAL 288
95#define NUM_LINES_1CIFS_PAL 288
96#define LINE_SZ_DEF 640
97#define NUM_LINES_DEF 240
98
99
100/* predefined settings */
101#define FORMAT_NTSC 1
102#define FORMAT_PAL 2
103
104#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
105#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
106#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300107/* SCALE_4CIFSI is the 2 fields interpolated into one */
108#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300109
110#define COLOR_YUVPL 1 /* YUV planar */
111#define COLOR_YUVPK 2 /* YUV packed */
112#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300113#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300114
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300115#define MASK_COLOR 0x000000ff
116#define MASK_JPG_QUALITY 0x0000ff00
117#define MASK_INPUT_TYPE 0x000f0000
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300118/* frame decimation. */
Dean Anderson38f993a2008-06-26 23:15:51 -0300119#define FDEC_1 1 /* capture every frame. default */
120#define FDEC_2 2 /* capture every 2nd frame */
121#define FDEC_3 3 /* capture every 3rd frame */
122#define FDEC_5 5 /* capture every 5th frame */
123
124/*-------------------------------------------------------
125 * Default mode parameters.
126 *-------------------------------------------------------*/
127#define DEF_SCALE SCALE_4CIFS
128#define DEF_COLOR COLOR_YUVPL
129#define DEF_FDEC FDEC_1
130#define DEF_BRIGHT 0
131#define DEF_CONTRAST 0x5c
132#define DEF_SATURATION 0x80
133#define DEF_HUE 0
134
135/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300136#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
Dan Carpenter3b2a6302012-02-17 02:44:10 -0300137#define CMD_2255 0xc2255000
Dean Anderson3fa00602010-03-04 20:47:33 -0300138#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
139#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
140#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
141#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300142
143struct s2255_mode {
144 u32 format; /* input video format (NTSC, PAL) */
145 u32 scale; /* output video scale */
146 u32 color; /* output video color format */
147 u32 fdec; /* frame decimation */
148 u32 bright; /* brightness */
149 u32 contrast; /* contrast */
150 u32 saturation; /* saturation */
151 u32 hue; /* hue (NTSC only)*/
152 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
153 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
154 u32 restart; /* if DSP requires restart */
155};
156
Dean Anderson14d96262008-08-25 13:58:55 -0300157
158#define S2255_READ_IDLE 0
159#define S2255_READ_FRAME 1
160
Dean Anderson38f993a2008-06-26 23:15:51 -0300161/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300162struct s2255_framei {
163 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300164 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300165 void *lpvbits; /* image data */
166 unsigned long cur_size; /* current data copied to it */
167};
168
169/* image buffer structure */
170struct s2255_bufferi {
171 unsigned long dwFrames; /* number of frames in buffer */
172 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
173};
174
175#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
176 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300177 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300178
179struct s2255_dmaqueue {
180 struct list_head active;
Dean Anderson38f993a2008-06-26 23:15:51 -0300181 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300182};
183
184/* for firmware loading, fw_state */
185#define S2255_FW_NOTLOADED 0
186#define S2255_FW_LOADED_DSPWAIT 1
187#define S2255_FW_SUCCESS 2
188#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300189#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300190#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300191/* 2255 read states */
192#define S2255_READ_IDLE 0
193#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300194struct s2255_fw {
195 int fw_loaded;
196 int fw_size;
197 struct urb *fw_urb;
198 atomic_t fw_state;
199 void *pfw_data;
200 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300201 const struct firmware *fw;
202};
203
204struct s2255_pipeinfo {
205 u32 max_transfer_size;
206 u32 cur_transfer_size;
207 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300208 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300209 void *stream_urb;
210 void *dev; /* back pointer to s2255_dev struct*/
211 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300212 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300213};
214
215struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300216struct s2255_dev;
217
218struct s2255_channel {
219 struct video_device vdev;
220 int resources;
221 struct s2255_dmaqueue vidq;
222 struct s2255_bufferi buffer;
223 struct s2255_mode mode;
224 /* jpeg compression */
225 struct v4l2_jpegcompression jc;
226 /* capture parameters (for high quality mode full size) */
227 struct v4l2_captureparm cap_parm;
228 int cur_frame;
229 int last_frame;
230
231 int b_acquire;
232 /* allocated image size */
233 unsigned long req_image_size;
234 /* received packet size */
235 unsigned long pkt_size;
236 int bad_payload;
237 unsigned long frame_count;
238 /* if JPEG image */
239 int jpg_size;
240 /* if channel configured to default state */
241 int configured;
242 wait_queue_head_t wait_setmode;
243 int setmode_ready;
244 /* video status items */
245 int vidstatus;
246 wait_queue_head_t wait_vidstatus;
247 int vidstatus_ready;
248 unsigned int width;
249 unsigned int height;
250 const struct s2255_fmt *fmt;
251 int idx; /* channel number on device, 0-3 */
252};
253
Dean Anderson38f993a2008-06-26 23:15:51 -0300254
255struct s2255_dev {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300256 struct s2255_channel channel[MAX_CHANNELS];
Dean Anderson65c6edb2010-04-20 17:21:32 -0300257 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300258 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300259 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300260 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson38f993a2008-06-26 23:15:51 -0300261 struct 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{
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300855 int index = f->index;
Dean Anderson38f993a2008-06-26 23:15:51 -0300856
857 if (index >= ARRAY_SIZE(formats))
858 return -EINVAL;
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300859 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
860 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
861 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300862 dprintk(4, "name %s\n", formats[index].name);
863 strlcpy(f->description, formats[index].name, sizeof(f->description));
864 f->pixelformat = formats[index].fourcc;
865 return 0;
866}
867
868static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
869 struct v4l2_format *f)
870{
871 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300872 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300873
Dean Andersonfe85ce92010-06-01 19:12:07 -0300874 f->fmt.pix.width = channel->width;
875 f->fmt.pix.height = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300876 f->fmt.pix.field = fh->vb_vidq.field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300877 f->fmt.pix.pixelformat = channel->fmt->fourcc;
878 f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300879 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300880 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300881}
882
883static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
884 struct v4l2_format *f)
885{
886 const struct s2255_fmt *fmt;
887 enum v4l2_field field;
888 int b_any_field = 0;
889 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300890 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300891 int is_ntsc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300892 is_ntsc =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300893 (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300894
895 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
896
897 if (fmt == NULL)
898 return -EINVAL;
899
900 field = f->fmt.pix.field;
901 if (field == V4L2_FIELD_ANY)
902 b_any_field = 1;
903
Dean Anderson85b85482010-04-08 23:51:17 -0300904 dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
905 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300906 if (is_ntsc) {
907 /* NTSC */
908 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
909 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
910 if (b_any_field) {
911 field = V4L2_FIELD_SEQ_TB;
912 } else if (!((field == V4L2_FIELD_INTERLACED) ||
913 (field == V4L2_FIELD_SEQ_TB) ||
914 (field == V4L2_FIELD_INTERLACED_TB))) {
915 dprintk(1, "unsupported field setting\n");
916 return -EINVAL;
917 }
918 } else {
919 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
920 if (b_any_field) {
921 field = V4L2_FIELD_TOP;
922 } else if (!((field == V4L2_FIELD_TOP) ||
923 (field == V4L2_FIELD_BOTTOM))) {
924 dprintk(1, "unsupported field setting\n");
925 return -EINVAL;
926 }
927
928 }
929 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
930 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
931 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
932 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
933 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
934 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
935 else
936 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
937 } else {
938 /* PAL */
939 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
940 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
941 if (b_any_field) {
942 field = V4L2_FIELD_SEQ_TB;
943 } else if (!((field == V4L2_FIELD_INTERLACED) ||
944 (field == V4L2_FIELD_SEQ_TB) ||
945 (field == V4L2_FIELD_INTERLACED_TB))) {
946 dprintk(1, "unsupported field setting\n");
947 return -EINVAL;
948 }
949 } else {
950 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
951 if (b_any_field) {
952 field = V4L2_FIELD_TOP;
953 } else if (!((field == V4L2_FIELD_TOP) ||
954 (field == V4L2_FIELD_BOTTOM))) {
955 dprintk(1, "unsupported field setting\n");
956 return -EINVAL;
957 }
958 }
959 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300960 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
961 field = V4L2_FIELD_SEQ_TB;
962 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300963 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
964 field = V4L2_FIELD_TOP;
965 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300966 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
967 field = V4L2_FIELD_TOP;
968 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300969 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
970 field = V4L2_FIELD_TOP;
971 }
972 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300973 f->fmt.pix.field = field;
974 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
975 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson85b85482010-04-08 23:51:17 -0300976 dprintk(50, "%s: set width %d height %d field %d\n", __func__,
977 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300978 return 0;
979}
980
981static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
982 struct v4l2_format *f)
983{
984 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300985 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300986 const struct s2255_fmt *fmt;
987 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300988 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300989 int ret;
990 int norm;
991
992 ret = vidioc_try_fmt_vid_cap(file, fh, f);
993
994 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300995 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300996
997 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
998
999 if (fmt == NULL)
1000 return -EINVAL;
1001
1002 mutex_lock(&q->vb_lock);
1003
1004 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1005 dprintk(1, "queue busy\n");
1006 ret = -EBUSY;
1007 goto out_s_fmt;
1008 }
1009
Dean Andersonfe85ce92010-06-01 19:12:07 -03001010 if (res_locked(fh)) {
Dean Anderson85b85482010-04-08 23:51:17 -03001011 dprintk(1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001012 ret = -EBUSY;
1013 goto out_s_fmt;
1014 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001015 mode = channel->mode;
1016 channel->fmt = fmt;
1017 channel->width = f->fmt.pix.width;
1018 channel->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -03001019 fh->vb_vidq.field = f->fmt.pix.field;
1020 fh->type = f->type;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001021 norm = norm_minw(&channel->vdev);
1022 if (channel->width > norm_minw(&channel->vdev)) {
1023 if (channel->height > norm_minh(&channel->vdev)) {
1024 if (channel->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -03001025 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001026 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -03001027 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001028 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -03001029 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001030 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001031
1032 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001033 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001034 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001035 /* color mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001036 switch (channel->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001037 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001038 mode.color &= ~MASK_COLOR;
1039 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001040 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001041 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -03001042 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001043 mode.color &= ~MASK_COLOR;
1044 mode.color |= COLOR_JPG;
1045 mode.color |= (channel->jc.quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001046 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001047 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001048 mode.color &= ~MASK_COLOR;
1049 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001050 break;
1051 case V4L2_PIX_FMT_YUYV:
1052 case V4L2_PIX_FMT_UYVY:
1053 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001054 mode.color &= ~MASK_COLOR;
1055 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001056 break;
1057 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001058 if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
1059 mode.restart = 1;
1060 else if (mode.scale != channel->mode.scale)
1061 mode.restart = 1;
1062 else if (mode.format != channel->mode.format)
1063 mode.restart = 1;
1064 channel->mode = mode;
1065 (void) s2255_set_mode(channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001066 ret = 0;
1067out_s_fmt:
1068 mutex_unlock(&q->vb_lock);
1069 return ret;
1070}
1071
1072static int vidioc_reqbufs(struct file *file, void *priv,
1073 struct v4l2_requestbuffers *p)
1074{
1075 int rc;
1076 struct s2255_fh *fh = priv;
1077 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1078 return rc;
1079}
1080
1081static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1082{
1083 int rc;
1084 struct s2255_fh *fh = priv;
1085 rc = videobuf_querybuf(&fh->vb_vidq, p);
1086 return rc;
1087}
1088
1089static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1090{
1091 int rc;
1092 struct s2255_fh *fh = priv;
1093 rc = videobuf_qbuf(&fh->vb_vidq, p);
1094 return rc;
1095}
1096
1097static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1098{
1099 int rc;
1100 struct s2255_fh *fh = priv;
1101 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1102 return rc;
1103}
1104
Dean Anderson38f993a2008-06-26 23:15:51 -03001105/* write to the configuration pipe, synchronously */
1106static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1107 int size)
1108{
1109 int pipe;
1110 int done;
1111 long retval = -1;
1112 if (udev) {
1113 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1114 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1115 }
1116 return retval;
1117}
1118
1119static u32 get_transfer_size(struct s2255_mode *mode)
1120{
1121 int linesPerFrame = LINE_SZ_DEF;
1122 int pixelsPerLine = NUM_LINES_DEF;
1123 u32 outImageSize;
1124 u32 usbInSize;
1125 unsigned int mask_mult;
1126
1127 if (mode == NULL)
1128 return 0;
1129
1130 if (mode->format == FORMAT_NTSC) {
1131 switch (mode->scale) {
1132 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001133 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001134 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1135 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1136 break;
1137 case SCALE_2CIFS:
1138 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1139 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1140 break;
1141 case SCALE_1CIFS:
1142 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1143 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1144 break;
1145 default:
1146 break;
1147 }
1148 } else if (mode->format == FORMAT_PAL) {
1149 switch (mode->scale) {
1150 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001151 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001152 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1153 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1154 break;
1155 case SCALE_2CIFS:
1156 linesPerFrame = NUM_LINES_2CIFS_PAL;
1157 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1158 break;
1159 case SCALE_1CIFS:
1160 linesPerFrame = NUM_LINES_1CIFS_PAL;
1161 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1162 break;
1163 default:
1164 break;
1165 }
1166 }
1167 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001168 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001169 /* 2 bytes/pixel if not monochrome */
1170 outImageSize *= 2;
1171 }
1172
1173 /* total bytes to send including prefix and 4K padding;
1174 must be a multiple of USB_READ_SIZE */
1175 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1176 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1177 /* if size not a multiple of USB_READ_SIZE */
1178 if (usbInSize & ~mask_mult)
1179 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1180 return usbInSize;
1181}
1182
Dean Anderson85b85482010-04-08 23:51:17 -03001183static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001184{
1185 struct device *dev = &sdev->udev->dev;
1186 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001187 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1188 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001189 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001190 dev_info(dev, "------------------------------------------------\n");
1191}
1192
1193/*
1194 * set mode is the function which controls the DSP.
1195 * the restart parameter in struct s2255_mode should be set whenever
1196 * the image size could change via color format, video system or image
1197 * size.
1198 * When the restart parameter is set, we sleep for ONE frame to allow the
1199 * DSP time to get the new frame
1200 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001201static int s2255_set_mode(struct s2255_channel *channel,
Dean Anderson38f993a2008-06-26 23:15:51 -03001202 struct s2255_mode *mode)
1203{
1204 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001205 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001206 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001207 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001208 chn_rev = G_chnmap[channel->idx];
1209 dprintk(3, "%s channel: %d\n", __func__, channel->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001210 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001211 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1212 mode->color &= ~MASK_COLOR;
1213 mode->color |= COLOR_JPG;
1214 mode->color &= ~MASK_JPG_QUALITY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001215 mode->color |= (channel->jc.quality << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001216 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001217 /* save the mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001218 channel->mode = *mode;
1219 channel->req_image_size = get_transfer_size(mode);
1220 dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001221 buffer = kzalloc(512, GFP_KERNEL);
1222 if (buffer == NULL) {
1223 dev_err(&dev->udev->dev, "out of mem\n");
1224 return -ENOMEM;
1225 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001226 /* set the mode */
1227 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001228 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001229 buffer[2] = CMD_SET_MODE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001230 memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
1231 channel->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001232 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1233 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001234 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001235 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001236 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001237 if (mode->restart) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001238 wait_event_timeout(channel->wait_setmode,
1239 (channel->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001240 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001241 if (channel->setmode_ready != 1) {
Dean Anderson14d96262008-08-25 13:58:55 -03001242 printk(KERN_DEBUG "s2255: no set mode response\n");
1243 res = -EFAULT;
1244 }
1245 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001246 /* clear the restart flag */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001247 channel->mode.restart = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001248 dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001249 return res;
1250}
1251
Dean Andersonfe85ce92010-06-01 19:12:07 -03001252static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001253{
1254 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001255 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001256 u32 chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001257 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001258 chn_rev = G_chnmap[channel->idx];
1259 dprintk(4, "%s chan %d\n", __func__, channel->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001260 buffer = kzalloc(512, GFP_KERNEL);
1261 if (buffer == NULL) {
1262 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001263 return -ENOMEM;
1264 }
1265 /* form the get vid status command */
1266 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001267 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001268 buffer[2] = CMD_STATUS;
1269 *pstatus = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001270 channel->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001271 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1272 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001273 wait_event_timeout(channel->wait_vidstatus,
1274 (channel->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001275 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001276 if (channel->vidstatus_ready != 1) {
Dean Anderson4de39f52010-03-03 19:39:19 -03001277 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1278 res = -EFAULT;
1279 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001280 *pstatus = channel->vidstatus;
Dean Anderson4de39f52010-03-03 19:39:19 -03001281 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03001282 return res;
1283}
1284
Dean Anderson38f993a2008-06-26 23:15:51 -03001285static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1286{
1287 int res;
1288 struct s2255_fh *fh = priv;
1289 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001290 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001291 int j;
1292 dprintk(4, "%s\n", __func__);
1293 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1294 dev_err(&dev->udev->dev, "invalid fh type0\n");
1295 return -EINVAL;
1296 }
1297 if (i != fh->type) {
1298 dev_err(&dev->udev->dev, "invalid fh type1\n");
1299 return -EINVAL;
1300 }
1301
Dean Andersonfe85ce92010-06-01 19:12:07 -03001302 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001303 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001304 return -EBUSY;
1305 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001306 channel->last_frame = -1;
1307 channel->bad_payload = 0;
1308 channel->cur_frame = 0;
1309 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001310 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001311 channel->buffer.frame[j].ulState = S2255_READ_IDLE;
1312 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001313 }
1314 res = videobuf_streamon(&fh->vb_vidq);
1315 if (res == 0) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001316 s2255_start_acquire(channel);
1317 channel->b_acquire = 1;
1318 } else
1319 res_free(fh);
1320
Dean Anderson38f993a2008-06-26 23:15:51 -03001321 return res;
1322}
1323
1324static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1325{
Dean Anderson38f993a2008-06-26 23:15:51 -03001326 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001327 dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001328 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1329 printk(KERN_ERR "invalid fh type0\n");
1330 return -EINVAL;
1331 }
1332 if (i != fh->type) {
1333 printk(KERN_ERR "invalid type i\n");
1334 return -EINVAL;
1335 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001336 s2255_stop_acquire(fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001337 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001338 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001339 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001340}
1341
1342static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1343{
1344 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001345 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001346 struct videobuf_queue *q = &fh->vb_vidq;
1347 int ret = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001348 mutex_lock(&q->vb_lock);
1349 if (videobuf_queue_is_busy(q)) {
1350 dprintk(1, "queue busy\n");
1351 ret = -EBUSY;
1352 goto out_s_std;
1353 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001354 if (res_locked(fh)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001355 dprintk(1, "can't change standard after started\n");
1356 ret = -EBUSY;
1357 goto out_s_std;
1358 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001359 mode = fh->channel->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001360 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001361 dprintk(4, "%s NTSC\n", __func__);
1362 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001363 if (mode.format != FORMAT_NTSC) {
1364 mode.restart = 1;
1365 mode.format = FORMAT_NTSC;
1366 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001367 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001368 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001369 dprintk(4, "%s PAL\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001370 if (mode.format != FORMAT_PAL) {
1371 mode.restart = 1;
1372 mode.format = FORMAT_PAL;
1373 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001374 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001375 } else {
1376 ret = -EINVAL;
1377 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001378 if (mode.restart)
1379 s2255_set_mode(fh->channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001380out_s_std:
1381 mutex_unlock(&q->vb_lock);
1382 return ret;
1383}
1384
1385/* Sensoray 2255 is a multiple channel capture device.
1386 It does not have a "crossbar" of inputs.
1387 We use one V4L device per channel. The user must
1388 be aware that certain combinations are not allowed.
1389 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1390 at once in color(you can do full fps on 4 channels with greyscale.
1391*/
1392static int vidioc_enum_input(struct file *file, void *priv,
1393 struct v4l2_input *inp)
1394{
Dean Anderson4de39f52010-03-03 19:39:19 -03001395 struct s2255_fh *fh = priv;
1396 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001397 struct s2255_channel *channel = fh->channel;
Dean Anderson4de39f52010-03-03 19:39:19 -03001398 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001399 if (inp->index != 0)
1400 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001401 inp->type = V4L2_INPUT_TYPE_CAMERA;
1402 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001403 inp->status = 0;
1404 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1405 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001406 rc = s2255_cmd_status(fh->channel, &status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001407 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1408 if (rc == 0)
1409 inp->status = (status & 0x01) ? 0
1410 : V4L2_IN_ST_NO_SIGNAL;
1411 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001412 switch (dev->pid) {
1413 case 0x2255:
1414 default:
1415 strlcpy(inp->name, "Composite", sizeof(inp->name));
1416 break;
1417 case 0x2257:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001418 strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001419 sizeof(inp->name));
1420 break;
1421 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001422 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001423}
1424
1425static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1426{
1427 *i = 0;
1428 return 0;
1429}
1430static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1431{
1432 if (i > 0)
1433 return -EINVAL;
1434 return 0;
1435}
1436
1437/* --- controls ---------------------------------------------- */
1438static int vidioc_queryctrl(struct file *file, void *priv,
1439 struct v4l2_queryctrl *qc)
1440{
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001441 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001442 struct s2255_channel *channel = fh->channel;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001443 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001444 switch (qc->id) {
1445 case V4L2_CID_BRIGHTNESS:
1446 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1447 break;
1448 case V4L2_CID_CONTRAST:
1449 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1450 break;
1451 case V4L2_CID_SATURATION:
1452 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1453 break;
1454 case V4L2_CID_HUE:
1455 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1456 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001457 case V4L2_CID_PRIVATE_COLORFILTER:
1458 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1459 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001460 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001461 return -EINVAL;
1462 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1463 qc->type = V4L2_CTRL_TYPE_MENU;
1464 qc->minimum = 0;
1465 qc->maximum = 1;
1466 qc->step = 1;
1467 qc->default_value = 1;
1468 qc->flags = 0;
1469 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001470 default:
1471 return -EINVAL;
1472 }
1473 dprintk(4, "%s, id %d\n", __func__, qc->id);
1474 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001475}
1476
1477static int vidioc_g_ctrl(struct file *file, void *priv,
1478 struct v4l2_control *ctrl)
1479{
Dean Anderson2e70db92010-03-05 14:29:09 -03001480 struct s2255_fh *fh = priv;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001481 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001482 struct s2255_channel *channel = fh->channel;
Dean Anderson2e70db92010-03-05 14:29:09 -03001483 switch (ctrl->id) {
1484 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001485 ctrl->value = channel->mode.bright;
Dean Anderson2e70db92010-03-05 14:29:09 -03001486 break;
1487 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001488 ctrl->value = channel->mode.contrast;
Dean Anderson2e70db92010-03-05 14:29:09 -03001489 break;
1490 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001491 ctrl->value = channel->mode.saturation;
Dean Anderson2e70db92010-03-05 14:29:09 -03001492 break;
1493 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001494 ctrl->value = channel->mode.hue;
Dean Anderson2e70db92010-03-05 14:29:09 -03001495 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001496 case V4L2_CID_PRIVATE_COLORFILTER:
1497 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1498 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001499 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001500 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001501 ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001502 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001503 default:
1504 return -EINVAL;
1505 }
1506 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1507 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001508}
1509
1510static int vidioc_s_ctrl(struct file *file, void *priv,
1511 struct v4l2_control *ctrl)
1512{
Dean Anderson38f993a2008-06-26 23:15:51 -03001513 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001514 struct s2255_channel *channel = fh->channel;
1515 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
1516 struct s2255_mode mode;
1517 mode = channel->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001518 dprintk(4, "%s\n", __func__);
1519 /* update the mode to the corresponding value */
1520 switch (ctrl->id) {
1521 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001522 mode.bright = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001523 break;
1524 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001525 mode.contrast = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001526 break;
1527 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001528 mode.hue = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001529 break;
1530 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001531 mode.saturation = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001532 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001533 case V4L2_CID_PRIVATE_COLORFILTER:
1534 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1535 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001536 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001537 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001538 mode.color &= ~MASK_INPUT_TYPE;
1539 mode.color |= ((ctrl->value ? 0 : 1) << 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001540 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001541 default:
1542 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001543 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001544 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001545 /* set mode here. Note: stream does not need restarted.
1546 some V4L programs restart stream unnecessarily
1547 after a s_crtl.
1548 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001549 s2255_set_mode(fh->channel, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001550 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001551}
1552
Dean Anderson22b88d42008-08-29 15:33:19 -03001553static int vidioc_g_jpegcomp(struct file *file, void *priv,
1554 struct v4l2_jpegcompression *jc)
1555{
1556 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001557 struct s2255_channel *channel = fh->channel;
1558 *jc = channel->jc;
Dean Anderson85b85482010-04-08 23:51:17 -03001559 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001560 return 0;
1561}
1562
1563static int vidioc_s_jpegcomp(struct file *file, void *priv,
1564 struct v4l2_jpegcompression *jc)
1565{
1566 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001567 struct s2255_channel *channel = fh->channel;
Dean Anderson22b88d42008-08-29 15:33:19 -03001568 if (jc->quality < 0 || jc->quality > 100)
1569 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001570 channel->jc.quality = jc->quality;
Dean Anderson85b85482010-04-08 23:51:17 -03001571 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001572 return 0;
1573}
Dean Anderson7d853532009-05-15 14:32:04 -03001574
1575static int vidioc_g_parm(struct file *file, void *priv,
1576 struct v4l2_streamparm *sp)
1577{
1578 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001579 __u32 def_num, def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001580 struct s2255_channel *channel = fh->channel;
Dean Anderson7d853532009-05-15 14:32:04 -03001581 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1582 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001583 memset(sp, 0, sizeof(struct v4l2_streamparm));
1584 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001585 sp->parm.capture.capturemode = channel->cap_parm.capturemode;
1586 def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1587 def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001588 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001589 switch (channel->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001590 default:
1591 case FDEC_1:
1592 sp->parm.capture.timeperframe.numerator = def_num;
1593 break;
1594 case FDEC_2:
1595 sp->parm.capture.timeperframe.numerator = def_num * 2;
1596 break;
1597 case FDEC_3:
1598 sp->parm.capture.timeperframe.numerator = def_num * 3;
1599 break;
1600 case FDEC_5:
1601 sp->parm.capture.timeperframe.numerator = def_num * 5;
1602 break;
1603 }
1604 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1605 sp->parm.capture.capturemode,
1606 sp->parm.capture.timeperframe.numerator,
1607 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001608 return 0;
1609}
1610
1611static int vidioc_s_parm(struct file *file, void *priv,
1612 struct v4l2_streamparm *sp)
1613{
1614 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001615 struct s2255_channel *channel = fh->channel;
1616 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001617 int fdec = FDEC_1;
1618 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001619 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1620 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001621 mode = channel->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001622 /* high quality capture mode requires a stream restart */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001623 if (channel->cap_parm.capturemode
1624 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001625 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001626 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1627 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001628 if (def_dem != sp->parm.capture.timeperframe.denominator)
1629 sp->parm.capture.timeperframe.numerator = def_num;
1630 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1631 sp->parm.capture.timeperframe.numerator = def_num;
1632 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1633 sp->parm.capture.timeperframe.numerator = def_num * 2;
1634 fdec = FDEC_2;
1635 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1636 sp->parm.capture.timeperframe.numerator = def_num * 3;
1637 fdec = FDEC_3;
1638 } else {
1639 sp->parm.capture.timeperframe.numerator = def_num * 5;
1640 fdec = FDEC_5;
1641 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001642 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001643 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001644 s2255_set_mode(channel, &mode);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001645 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1646 __func__,
1647 sp->parm.capture.capturemode,
1648 sp->parm.capture.timeperframe.numerator,
1649 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001650 return 0;
1651}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001652
1653static int vidioc_enum_frameintervals(struct file *file, void *priv,
1654 struct v4l2_frmivalenum *fe)
1655{
1656 int is_ntsc = 0;
1657#define NUM_FRAME_ENUMS 4
1658 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
1659 if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
1660 return -EINVAL;
1661 switch (fe->width) {
1662 case 640:
1663 if (fe->height != 240 && fe->height != 480)
1664 return -EINVAL;
1665 is_ntsc = 1;
1666 break;
1667 case 320:
1668 if (fe->height != 240)
1669 return -EINVAL;
1670 is_ntsc = 1;
1671 break;
1672 case 704:
1673 if (fe->height != 288 && fe->height != 576)
1674 return -EINVAL;
1675 break;
1676 case 352:
1677 if (fe->height != 288)
1678 return -EINVAL;
1679 break;
1680 default:
1681 return -EINVAL;
1682 }
1683 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1684 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1685 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1686 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1687 fe->discrete.denominator);
1688 return 0;
1689}
1690
Hans Verkuilbec43662008-12-30 06:58:20 -03001691static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001692{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001693 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001694 struct s2255_channel *channel = video_drvdata(file);
1695 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001696 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001697 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001698 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001699 dprintk(1, "s2255: open called (dev=%s)\n",
1700 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001701 /*
1702 * open lock necessary to prevent multiple instances
1703 * of v4l-conf (or other programs) from simultaneously
1704 * reloading firmware.
1705 */
Dean Anderson38f993a2008-06-26 23:15:51 -03001706 mutex_lock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001707 state = atomic_read(&dev->fw_data->fw_state);
1708 switch (state) {
1709 case S2255_FW_DISCONNECTING:
1710 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001711 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001712 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001713 s2255_dev_err(&dev->udev->dev,
1714 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001715 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001716 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001717 ((atomic_read(&dev->fw_data->fw_state)
1718 == S2255_FW_SUCCESS) ||
1719 (atomic_read(&dev->fw_data->fw_state)
1720 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001721 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001722 /* state may have changed, re-read */
1723 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001724 break;
1725 case S2255_FW_NOTLOADED:
1726 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001727 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1728 driver loaded and then device immediately opened */
1729 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1730 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001731 ((atomic_read(&dev->fw_data->fw_state)
1732 == S2255_FW_SUCCESS) ||
1733 (atomic_read(&dev->fw_data->fw_state)
1734 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001735 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001736 /* state may have changed, re-read */
1737 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001738 break;
1739 case S2255_FW_SUCCESS:
1740 default:
1741 break;
1742 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001743 /* state may have changed in above switch statement */
1744 switch (state) {
1745 case S2255_FW_SUCCESS:
1746 break;
1747 case S2255_FW_FAILED:
1748 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Andersoneb78dee2010-04-12 15:05:37 -03001749 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001750 return -ENODEV;
1751 case S2255_FW_DISCONNECTING:
1752 printk(KERN_INFO "%s: disconnecting\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001753 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001754 return -ENODEV;
1755 case S2255_FW_LOADED_DSPWAIT:
1756 case S2255_FW_NOTLOADED:
1757 printk(KERN_INFO "%s: firmware not loaded yet"
1758 "please try again later\n",
1759 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001760 /*
1761 * Timeout on firmware load means device unusable.
1762 * Set firmware failure state.
1763 * On next s2255_open the firmware will be reloaded.
1764 */
1765 atomic_set(&dev->fw_data->fw_state,
1766 S2255_FW_FAILED);
1767 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001768 return -EAGAIN;
1769 default:
1770 printk(KERN_INFO "%s: unknown state\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001771 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001772 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001773 }
Dean Andersoneb78dee2010-04-12 15:05:37 -03001774 mutex_unlock(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001775 /* allocate + initialize per filehandle data */
1776 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001777 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001778 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03001779 file->private_data = fh;
1780 fh->dev = dev;
1781 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001782 fh->channel = channel;
1783 if (!channel->configured) {
1784 /* configure channel to default state */
1785 channel->fmt = &formats[0];
1786 s2255_set_mode(channel, &channel->mode);
1787 channel->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001788 }
Dean Anderson85b85482010-04-08 23:51:17 -03001789 dprintk(1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001790 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson85b85482010-04-08 23:51:17 -03001791 dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001792 (unsigned long)fh, (unsigned long)dev,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001793 (unsigned long)&channel->vidq);
Dean Anderson85b85482010-04-08 23:51:17 -03001794 dprintk(4, "%s: list_empty active=%d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001795 list_empty(&channel->vidq.active));
Dean Anderson38f993a2008-06-26 23:15:51 -03001796 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1797 NULL, &dev->slock,
1798 fh->type,
1799 V4L2_FIELD_INTERLACED,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001800 sizeof(struct s2255_buffer),
1801 fh, vdev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001802 return 0;
1803}
1804
1805
1806static unsigned int s2255_poll(struct file *file,
1807 struct poll_table_struct *wait)
1808{
1809 struct s2255_fh *fh = file->private_data;
1810 int rc;
1811 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001812 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1813 return POLLERR;
Dean Anderson38f993a2008-06-26 23:15:51 -03001814 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
1815 return rc;
1816}
1817
Dean Andersond62e85a2010-04-09 19:54:26 -03001818static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001819{
Dean Anderson38f993a2008-06-26 23:15:51 -03001820 /* board shutdown stops the read pipe if it is running */
1821 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001822 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001823 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001824 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001825 usb_kill_urb(dev->fw_data->fw_urb);
1826 usb_free_urb(dev->fw_data->fw_urb);
1827 dev->fw_data->fw_urb = NULL;
1828 }
Jesper Juhl3fc82fa2012-04-09 16:50:04 -03001829 release_firmware(dev->fw_data->fw);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001830 kfree(dev->fw_data->pfw_data);
1831 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001832 /* reset the DSP so firmware can be reloaded next time */
1833 s2255_reset_dsppower(dev);
1834 mutex_destroy(&dev->open_lock);
1835 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001836 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001837 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001838 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001839 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001840}
1841
Dean Andersonff7e22d2010-04-08 23:38:07 -03001842static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001843{
1844 struct s2255_fh *fh = file->private_data;
1845 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001846 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001847 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001848 if (!dev)
1849 return -ENODEV;
Dean Andersonf78d92c2008-07-22 14:43:27 -03001850 /* turn off stream */
1851 if (res_check(fh)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001852 if (channel->b_acquire)
1853 s2255_stop_acquire(fh->channel);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001854 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001855 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001856 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001857 videobuf_mmap_free(&fh->vb_vidq);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001858 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001859 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001860 return 0;
1861}
1862
1863static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1864{
1865 struct s2255_fh *fh = file->private_data;
1866 int ret;
1867
1868 if (!fh)
1869 return -ENODEV;
Dean Anderson85b85482010-04-08 23:51:17 -03001870 dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Dean Anderson38f993a2008-06-26 23:15:51 -03001871 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
Dean Anderson85b85482010-04-08 23:51:17 -03001872 dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001873 (unsigned long)vma->vm_start,
1874 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001875 return ret;
1876}
1877
Hans Verkuilbec43662008-12-30 06:58:20 -03001878static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001879 .owner = THIS_MODULE,
1880 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001881 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001882 .poll = s2255_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001883 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001884 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001885};
1886
Hans Verkuila3998102008-07-21 02:57:38 -03001887static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001888 .vidioc_querymenu = vidioc_querymenu,
Dean Anderson38f993a2008-06-26 23:15:51 -03001889 .vidioc_querycap = vidioc_querycap,
1890 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1891 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1892 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1893 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1894 .vidioc_reqbufs = vidioc_reqbufs,
1895 .vidioc_querybuf = vidioc_querybuf,
1896 .vidioc_qbuf = vidioc_qbuf,
1897 .vidioc_dqbuf = vidioc_dqbuf,
1898 .vidioc_s_std = vidioc_s_std,
1899 .vidioc_enum_input = vidioc_enum_input,
1900 .vidioc_g_input = vidioc_g_input,
1901 .vidioc_s_input = vidioc_s_input,
1902 .vidioc_queryctrl = vidioc_queryctrl,
1903 .vidioc_g_ctrl = vidioc_g_ctrl,
1904 .vidioc_s_ctrl = vidioc_s_ctrl,
1905 .vidioc_streamon = vidioc_streamon,
1906 .vidioc_streamoff = vidioc_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001907 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1908 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001909 .vidioc_s_parm = vidioc_s_parm,
1910 .vidioc_g_parm = vidioc_g_parm,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001911 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuila3998102008-07-21 02:57:38 -03001912};
1913
Dean Andersonff7e22d2010-04-08 23:38:07 -03001914static void s2255_video_device_release(struct video_device *vdev)
1915{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001916 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
1917 dprintk(4, "%s, chnls: %d \n", __func__,
1918 atomic_read(&dev->num_channels));
1919 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001920 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001921 return;
1922}
1923
Hans Verkuila3998102008-07-21 02:57:38 -03001924static struct video_device template = {
1925 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001926 .fops = &s2255_fops_v4l,
1927 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001928 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001929 .tvnorms = S2255_NORMS,
1930 .current_norm = V4L2_STD_NTSC_M,
1931};
1932
1933static int s2255_probe_v4l(struct s2255_dev *dev)
1934{
1935 int ret;
1936 int i;
1937 int cur_nr = video_nr;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001938 struct s2255_channel *channel;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001939 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1940 if (ret)
1941 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001942 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001943 /* register 4 video devices */
1944 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001945 channel = &dev->channel[i];
1946 INIT_LIST_HEAD(&channel->vidq.active);
1947 channel->vidq.dev = dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001948 /* register 4 video devices */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001949 channel->vdev = template;
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001950 channel->vdev.lock = &dev->lock;
Hans Verkuil5126f252012-05-10 04:57:22 -03001951 /* Locking in file operations other than ioctl should be done
1952 by the driver, not the V4L2 core.
1953 This driver needs auditing so that this flag can be removed. */
1954 set_bit(V4L2_FL_LOCK_ALL_FOPS, &channel->vdev.flags);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001955 channel->vdev.v4l2_dev = &dev->v4l2_dev;
1956 video_set_drvdata(&channel->vdev, channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03001957 if (video_nr == -1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001958 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001959 VFL_TYPE_GRABBER,
1960 video_nr);
1961 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001962 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001963 VFL_TYPE_GRABBER,
1964 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001965
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001966 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001967 dev_err(&dev->udev->dev,
1968 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001969 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001970 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001971 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001972 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001973 video_device_node_name(&channel->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001974
Dean Anderson38f993a2008-06-26 23:15:51 -03001975 }
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03001976 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %s\n",
1977 S2255_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001978 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001979 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001980 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001981 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001982 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001983 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001984 printk(KERN_WARNING "s2255: Not all channels available.\n");
1985 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001986}
1987
Dean Anderson38f993a2008-06-26 23:15:51 -03001988/* this function moves the usb stream read pipe data
1989 * into the system buffers.
1990 * returns 0 on success, EAGAIN if more data to process( call this
1991 * function again).
1992 *
1993 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001994 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001995 * bytes 4-7: channel: 0-3
1996 * bytes 8-11: payload size: size of the frame
1997 * bytes 12-payloadsize+12: frame data
1998 */
1999static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
2000{
Dean Anderson38f993a2008-06-26 23:15:51 -03002001 char *pdest;
2002 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002003 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002004 char *psrc;
2005 unsigned long copy_size;
2006 unsigned long size;
2007 s32 idx = -1;
2008 struct s2255_framei *frm;
2009 unsigned char *pdata;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002010 struct s2255_channel *channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03002011 dprintk(100, "buffer to user\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002012 channel = &dev->channel[dev->cc];
2013 idx = channel->cur_frame;
2014 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002015 if (frm->ulState == S2255_READ_IDLE) {
2016 int jj;
2017 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03002018 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03002019 int payload;
2020 /* search for marker codes */
2021 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03002022 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002023 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03002024 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03002025 case S2255_MARKER_FRAME:
Dean Anderson14d96262008-08-25 13:58:55 -03002026 dprintk(4, "found frame marker at offset:"
2027 " %d [%x %x]\n", jj, pdata[0],
2028 pdata[1]);
2029 offset = jj + PREFIX_SIZE;
2030 bframe = 1;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002031 cc = le32_to_cpu(pdword[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03002032 if (cc >= MAX_CHANNELS) {
2033 printk(KERN_ERR
2034 "bad channel\n");
2035 return -EINVAL;
2036 }
2037 /* reverse it */
2038 dev->cc = G_chnmap[cc];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002039 channel = &dev->channel[dev->cc];
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002040 payload = le32_to_cpu(pdword[3]);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002041 if (payload > channel->req_image_size) {
2042 channel->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03002043 /* discard the bad frame */
2044 return -EINVAL;
2045 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002046 channel->pkt_size = payload;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002047 channel->jpg_size = le32_to_cpu(pdword[4]);
Dean Anderson14d96262008-08-25 13:58:55 -03002048 break;
2049 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002050
Dean Anderson14d96262008-08-25 13:58:55 -03002051 pdata += DEF_USB_BLOCK;
2052 jj += DEF_USB_BLOCK;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002053 if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002054 break;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002055 cc = G_chnmap[le32_to_cpu(pdword[1])];
Roel Kluinf14a2972009-10-23 07:59:42 -03002056 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002057 break;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002058 channel = &dev->channel[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002059 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03002060 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03002061 /* check if channel valid */
2062 /* set mode ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002063 channel->setmode_ready = 1;
2064 wake_up(&channel->wait_setmode);
Dean Anderson14d96262008-08-25 13:58:55 -03002065 dprintk(5, "setmode ready %d\n", cc);
2066 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002067 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002068 dev->chn_ready |= (1 << cc);
2069 if ((dev->chn_ready & 0x0f) != 0x0f)
2070 break;
2071 /* all channels ready */
2072 printk(KERN_INFO "s2255: fw loaded\n");
2073 atomic_set(&dev->fw_data->fw_state,
2074 S2255_FW_SUCCESS);
2075 wake_up(&dev->fw_data->wait_fw);
2076 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002077 case S2255_RESPONSE_STATUS:
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002078 channel->vidstatus = le32_to_cpu(pdword[3]);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002079 channel->vidstatus_ready = 1;
2080 wake_up(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002081 dprintk(5, "got vidstatus %x chan %d\n",
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002082 le32_to_cpu(pdword[3]), cc);
Dean Anderson4de39f52010-03-03 19:39:19 -03002083 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002084 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02002085 printk(KERN_INFO "s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002086 }
2087 default:
2088 pdata++;
2089 break;
2090 }
2091 if (bframe)
2092 break;
2093 } /* for */
2094 if (!bframe)
2095 return -EINVAL;
2096 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002097 channel = &dev->channel[dev->cc];
2098 idx = channel->cur_frame;
2099 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002100 /* search done. now find out if should be acquiring on this channel */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002101 if (!channel->b_acquire) {
Dean Anderson14d96262008-08-25 13:58:55 -03002102 /* we found a frame, but this channel is turned off */
2103 frm->ulState = S2255_READ_IDLE;
2104 return -EINVAL;
2105 }
2106
2107 if (frm->ulState == S2255_READ_IDLE) {
2108 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002109 frm->cur_size = 0;
2110 }
2111
Dean Anderson14d96262008-08-25 13:58:55 -03002112 /* skip the marker 512 bytes (and offset if out of sync) */
2113 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2114
Dean Anderson38f993a2008-06-26 23:15:51 -03002115
2116 if (frm->lpvbits == NULL) {
2117 dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
2118 frm, dev, dev->cc, idx);
2119 return -ENOMEM;
2120 }
2121
2122 pdest = frm->lpvbits + frm->cur_size;
2123
Dean Anderson14d96262008-08-25 13:58:55 -03002124 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002125
Dean Andersonfe85ce92010-06-01 19:12:07 -03002126 size = channel->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002127
Dean Anderson14d96262008-08-25 13:58:55 -03002128 /* sanity check on pdest */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002129 if ((copy_size + frm->cur_size) < channel->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03002130 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002131
Dean Anderson38f993a2008-06-26 23:15:51 -03002132 frm->cur_size += copy_size;
Dean Anderson14d96262008-08-25 13:58:55 -03002133 dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002134
Dean Anderson14d96262008-08-25 13:58:55 -03002135 if (frm->cur_size >= size) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002136 dprintk(2, "****************[%d]Buffer[%d]full*************\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002137 dev->cc, idx);
2138 channel->last_frame = channel->cur_frame;
2139 channel->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002140 /* end of system frame ring buffer, start at zero */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002141 if ((channel->cur_frame == SYS_FRAMES) ||
2142 (channel->cur_frame == channel->buffer.dwFrames))
2143 channel->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002144 /* frame ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002145 if (channel->b_acquire)
2146 s2255_got_frame(channel, channel->jpg_size);
2147 channel->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03002148 frm->ulState = S2255_READ_IDLE;
2149 frm->cur_size = 0;
2150
Dean Anderson38f993a2008-06-26 23:15:51 -03002151 }
2152 /* done successfully */
2153 return 0;
2154}
2155
2156static void s2255_read_video_callback(struct s2255_dev *dev,
2157 struct s2255_pipeinfo *pipe_info)
2158{
2159 int res;
2160 dprintk(50, "callback read video \n");
2161
2162 if (dev->cc >= MAX_CHANNELS) {
2163 dev->cc = 0;
2164 dev_err(&dev->udev->dev, "invalid channel\n");
2165 return;
2166 }
2167 /* otherwise copy to the system buffers */
2168 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002169 if (res != 0)
2170 dprintk(4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002171
2172 dprintk(50, "callback read video done\n");
2173 return;
2174}
2175
2176static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2177 u16 Index, u16 Value, void *TransferBuffer,
2178 s32 TransferBufferLength, int bOut)
2179{
2180 int r;
2181 if (!bOut) {
2182 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2183 Request,
2184 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2185 USB_DIR_IN,
2186 Value, Index, TransferBuffer,
2187 TransferBufferLength, HZ * 5);
2188 } else {
2189 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2190 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2191 Value, Index, TransferBuffer,
2192 TransferBufferLength, HZ * 5);
2193 }
2194 return r;
2195}
2196
2197/*
2198 * retrieve FX2 firmware version. future use.
2199 * @param dev pointer to device extension
2200 * @return -1 for fail, else returns firmware version as an int(16 bits)
2201 */
2202static int s2255_get_fx2fw(struct s2255_dev *dev)
2203{
2204 int fw;
2205 int ret;
2206 unsigned char transBuffer[64];
2207 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2208 S2255_VR_IN);
2209 if (ret < 0)
2210 dprintk(2, "get fw error: %x\n", ret);
2211 fw = transBuffer[0] + (transBuffer[1] << 8);
2212 dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
2213 return fw;
2214}
2215
2216/*
2217 * Create the system ring buffer to copy frames into from the
2218 * usb read pipe.
2219 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002220static int s2255_create_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002221{
2222 unsigned long i;
2223 unsigned long reqsize;
2224 dprintk(1, "create sys buffers\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002225 channel->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03002226 /* always allocate maximum size(PAL) for system buffers */
2227 reqsize = SYS_FRAMES_MAXSIZE;
2228
2229 if (reqsize > SYS_FRAMES_MAXSIZE)
2230 reqsize = SYS_FRAMES_MAXSIZE;
2231
2232 for (i = 0; i < SYS_FRAMES; i++) {
2233 /* allocate the frames */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002234 channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
2235 dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
2236 &channel->buffer.frame[i], channel->idx, i,
2237 channel->buffer.frame[i].lpvbits);
2238 channel->buffer.frame[i].size = reqsize;
2239 if (channel->buffer.frame[i].lpvbits == NULL) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002240 printk(KERN_INFO "out of memory. using less frames\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002241 channel->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002242 break;
2243 }
2244 }
2245
2246 /* make sure internal states are set */
2247 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002248 channel->buffer.frame[i].ulState = 0;
2249 channel->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002250 }
2251
Dean Andersonfe85ce92010-06-01 19:12:07 -03002252 channel->cur_frame = 0;
2253 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002254 return 0;
2255}
2256
Dean Andersonfe85ce92010-06-01 19:12:07 -03002257static int s2255_release_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002258{
2259 unsigned long i;
2260 dprintk(1, "release sys buffers\n");
2261 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002262 if (channel->buffer.frame[i].lpvbits) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002263 dprintk(1, "vfree %p\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002264 channel->buffer.frame[i].lpvbits);
2265 vfree(channel->buffer.frame[i].lpvbits);
Dean Anderson38f993a2008-06-26 23:15:51 -03002266 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002267 channel->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002268 }
2269 return 0;
2270}
2271
2272static int s2255_board_init(struct s2255_dev *dev)
2273{
Dean Anderson38f993a2008-06-26 23:15:51 -03002274 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2275 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002276 int j;
2277 struct s2255_pipeinfo *pipe = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002278 dprintk(4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002279 memset(pipe, 0, sizeof(*pipe));
2280 pipe->dev = dev;
2281 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2282 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002283
Dean Andersonab85c6a2010-04-08 23:39:12 -03002284 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2285 GFP_KERNEL);
2286 if (pipe->transfer_buffer == NULL) {
2287 dprintk(1, "out of memory!\n");
2288 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002289 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002290 /* query the firmware */
2291 fw_ver = s2255_get_fx2fw(dev);
2292
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -03002293 printk(KERN_INFO "s2255: usb firmware version %d.%d\n",
Dean Andersonabce21f2009-04-23 16:04:41 -03002294 (fw_ver >> 8) & 0xff,
2295 fw_ver & 0xff);
2296
2297 if (fw_ver < S2255_CUR_USB_FWVER)
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -03002298 printk(KERN_INFO "s2255: newer USB firmware available\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002299
2300 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002301 struct s2255_channel *channel = &dev->channel[j];
2302 channel->b_acquire = 0;
2303 channel->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002304 if (dev->pid == 0x2257 && j > 1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002305 channel->mode.color |= (1 << 16);
2306 channel->jc.quality = S2255_DEF_JPEG_QUAL;
2307 channel->width = LINE_SZ_4CIFS_NTSC;
2308 channel->height = NUM_LINES_4CIFS_NTSC * 2;
2309 channel->fmt = &formats[0];
2310 channel->mode.restart = 1;
2311 channel->req_image_size = get_transfer_size(&mode_def);
2312 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002313 /* create the system buffers */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002314 s2255_create_sys_buffers(channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03002315 }
2316 /* start read pipe */
2317 s2255_start_readpipe(dev);
Dean Anderson85b85482010-04-08 23:51:17 -03002318 dprintk(1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002319 return 0;
2320}
2321
2322static int s2255_board_shutdown(struct s2255_dev *dev)
2323{
2324 u32 i;
Dean Anderson85b85482010-04-08 23:51:17 -03002325 dprintk(1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002326
2327 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002328 if (dev->channel[i].b_acquire)
2329 s2255_stop_acquire(&dev->channel[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002330 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002331 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002332 for (i = 0; i < MAX_CHANNELS; i++)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002333 s2255_release_sys_buffers(&dev->channel[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002334 /* release transfer buffer */
2335 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002336 return 0;
2337}
2338
2339static void read_pipe_completion(struct urb *purb)
2340{
2341 struct s2255_pipeinfo *pipe_info;
2342 struct s2255_dev *dev;
2343 int status;
2344 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002345 pipe_info = purb->context;
Dean Anderson85b85482010-04-08 23:51:17 -03002346 dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
Dean Anderson38f993a2008-06-26 23:15:51 -03002347 purb->status);
2348 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002349 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002350 return;
2351 }
2352
2353 dev = pipe_info->dev;
2354 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002355 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002356 return;
2357 }
2358 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002359 /* if shutting down, do not resubmit, exit immediately */
2360 if (status == -ESHUTDOWN) {
Dean Anderson85b85482010-04-08 23:51:17 -03002361 dprintk(2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002362 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002363 return;
2364 }
2365
2366 if (pipe_info->state == 0) {
Dean Anderson85b85482010-04-08 23:51:17 -03002367 dprintk(2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002368 return;
2369 }
2370
Dean Andersonb02064c2009-04-30 12:29:38 -03002371 if (status == 0)
2372 s2255_read_video_callback(dev, pipe_info);
2373 else {
2374 pipe_info->err_count++;
Dean Anderson85b85482010-04-08 23:51:17 -03002375 dprintk(1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002376 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002377
Dean Anderson38f993a2008-06-26 23:15:51 -03002378 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2379 /* reuse urb */
2380 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2381 pipe,
2382 pipe_info->transfer_buffer,
2383 pipe_info->cur_transfer_size,
2384 read_pipe_completion, pipe_info);
2385
2386 if (pipe_info->state != 0) {
Pete Eberleina1b4c862011-04-01 21:21:26 -03002387 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002388 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002389 }
2390 } else {
Dean Anderson85b85482010-04-08 23:51:17 -03002391 dprintk(2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002392 }
2393 return;
2394}
2395
2396static int s2255_start_readpipe(struct s2255_dev *dev)
2397{
2398 int pipe;
2399 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002400 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002401 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
Dean Anderson85b85482010-04-08 23:51:17 -03002402 dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002403 pipe_info->state = 1;
2404 pipe_info->err_count = 0;
2405 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2406 if (!pipe_info->stream_urb) {
2407 dev_err(&dev->udev->dev,
2408 "ReadStream: Unable to alloc URB\n");
2409 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002410 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002411 /* transfer buffer allocated in board_init */
2412 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2413 pipe,
2414 pipe_info->transfer_buffer,
2415 pipe_info->cur_transfer_size,
2416 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002417 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2418 if (retval) {
2419 printk(KERN_ERR "s2255: start read pipe failed\n");
2420 return retval;
2421 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002422 return 0;
2423}
2424
2425/* starts acquisition process */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002426static int s2255_start_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002427{
2428 unsigned char *buffer;
2429 int res;
2430 unsigned long chn_rev;
2431 int j;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002432 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2433 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002434 buffer = kzalloc(512, GFP_KERNEL);
2435 if (buffer == NULL) {
2436 dev_err(&dev->udev->dev, "out of mem\n");
2437 return -ENOMEM;
2438 }
2439
Dean Andersonfe85ce92010-06-01 19:12:07 -03002440 channel->last_frame = -1;
2441 channel->bad_payload = 0;
2442 channel->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002443 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002444 channel->buffer.frame[j].ulState = 0;
2445 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002446 }
2447
2448 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002449 *(__le32 *) buffer = IN_DATA_TOKEN;
2450 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2451 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002452 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2453 if (res != 0)
2454 dev_err(&dev->udev->dev, "CMD_START error\n");
2455
Dean Andersonfe85ce92010-06-01 19:12:07 -03002456 dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03002457 kfree(buffer);
2458 return 0;
2459}
2460
Dean Andersonfe85ce92010-06-01 19:12:07 -03002461static int s2255_stop_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002462{
2463 unsigned char *buffer;
2464 int res;
2465 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002466 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2467 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002468 buffer = kzalloc(512, GFP_KERNEL);
2469 if (buffer == NULL) {
2470 dev_err(&dev->udev->dev, "out of mem\n");
2471 return -ENOMEM;
2472 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002473 /* send the stop command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002474 *(__le32 *) buffer = IN_DATA_TOKEN;
2475 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2476 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002477 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002478 if (res != 0)
2479 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002480 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002481 channel->b_acquire = 0;
2482 dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
Dean Anderson14d96262008-08-25 13:58:55 -03002483 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002484}
2485
2486static void s2255_stop_readpipe(struct s2255_dev *dev)
2487{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002488 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002489
Dean Andersonab85c6a2010-04-08 23:39:12 -03002490 pipe->state = 0;
2491 if (pipe->stream_urb) {
2492 /* cancel urb */
2493 usb_kill_urb(pipe->stream_urb);
2494 usb_free_urb(pipe->stream_urb);
2495 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002496 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002497 dprintk(4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002498 return;
2499}
2500
Dean Anderson14d96262008-08-25 13:58:55 -03002501static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002502{
Dean Anderson14d96262008-08-25 13:58:55 -03002503 if (reset)
2504 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002505 dev->fw_data->fw_size = dev->fw_data->fw->size;
2506 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2507 memcpy(dev->fw_data->pfw_data,
2508 dev->fw_data->fw->data, CHUNK_SIZE);
2509 dev->fw_data->fw_loaded = CHUNK_SIZE;
2510 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2511 usb_sndbulkpipe(dev->udev, 2),
2512 dev->fw_data->pfw_data,
2513 CHUNK_SIZE, s2255_fwchunk_complete,
2514 dev->fw_data);
2515 mod_timer(&dev->timer, jiffies + HZ);
2516}
2517
2518/* standard usb probe function */
2519static int s2255_probe(struct usb_interface *interface,
2520 const struct usb_device_id *id)
2521{
2522 struct s2255_dev *dev = NULL;
2523 struct usb_host_interface *iface_desc;
2524 struct usb_endpoint_descriptor *endpoint;
2525 int i;
2526 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002527 __le32 *pdata;
2528 int fw_size;
Dean Anderson85b85482010-04-08 23:51:17 -03002529 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002530 /* allocate memory for our device state and initialize it to zero */
2531 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2532 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002533 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002534 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002535 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002536 atomic_set(&dev->num_channels, 0);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002537 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002538 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2539 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002540 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002541 mutex_init(&dev->lock);
2542 mutex_init(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002543 /* grab usb_device and save it */
2544 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2545 if (dev->udev == NULL) {
2546 dev_err(&interface->dev, "null usb device\n");
2547 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002548 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002549 }
Dean Andersond62e85a2010-04-09 19:54:26 -03002550 dprintk(1, "dev: %p, udev %p interface %p\n", dev,
Dean Anderson38f993a2008-06-26 23:15:51 -03002551 dev->udev, interface);
2552 dev->interface = interface;
2553 /* set up the endpoint information */
2554 iface_desc = interface->cur_altsetting;
2555 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2556 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2557 endpoint = &iface_desc->endpoint[i].desc;
2558 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2559 /* we found the bulk in endpoint */
2560 dev->read_endpoint = endpoint->bEndpointAddress;
2561 }
2562 }
2563
2564 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002565 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002566 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002567 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002568 init_timer(&dev->timer);
2569 dev->timer.function = s2255_timer;
2570 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002571 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002572 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002573 struct s2255_channel *channel = &dev->channel[i];
2574 dev->channel[i].idx = i;
2575 init_waitqueue_head(&channel->wait_setmode);
2576 init_waitqueue_head(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002577 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002578
2579 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002580 if (!dev->fw_data->fw_urb) {
2581 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002582 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002583 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002584
Dean Anderson38f993a2008-06-26 23:15:51 -03002585 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2586 if (!dev->fw_data->pfw_data) {
2587 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002588 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002589 }
2590 /* load the first chunk */
2591 if (request_firmware(&dev->fw_data->fw,
2592 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2593 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002594 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002595 }
Dean Anderson14d96262008-08-25 13:58:55 -03002596 /* check the firmware is valid */
2597 fw_size = dev->fw_data->fw->size;
2598 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002599
Dean Anderson14d96262008-08-25 13:58:55 -03002600 if (*pdata != S2255_FW_MARKER) {
2601 printk(KERN_INFO "Firmware invalid.\n");
2602 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002603 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002604 } else {
2605 /* make sure firmware is the latest */
2606 __le32 *pRel;
2607 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2608 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002609 dev->dsp_fw_ver = le32_to_cpu(*pRel);
2610 if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
Dean Anderson4de39f52010-03-03 19:39:19 -03002611 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002612 if (dev->pid == 0x2257 &&
2613 dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002614 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
Dean Andersonfe85ce92010-06-01 19:12:07 -03002615 " or above.\n", S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002616 }
Dean Anderson14d96262008-08-25 13:58:55 -03002617 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002618 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002619 retval = s2255_board_init(dev);
2620 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002621 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002622 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002623 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002624 /* loads v4l specific */
2625 retval = s2255_probe_v4l(dev);
2626 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002627 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002628 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2629 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002630errorBOARDINIT:
2631 s2255_board_shutdown(dev);
2632errorFWMARKER:
2633 release_firmware(dev->fw_data->fw);
2634errorREQFW:
2635 kfree(dev->fw_data->pfw_data);
2636errorFWDATA2:
2637 usb_free_urb(dev->fw_data->fw_urb);
2638errorFWURB:
2639 del_timer(&dev->timer);
2640errorEP:
2641 usb_put_dev(dev->udev);
2642errorUDEV:
2643 kfree(dev->fw_data);
2644 mutex_destroy(&dev->open_lock);
2645 mutex_destroy(&dev->lock);
2646errorFWDATA1:
2647 kfree(dev);
2648 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002649 return retval;
2650}
2651
2652/* disconnect routine. when board is removed physically or with rmmod */
2653static void s2255_disconnect(struct usb_interface *interface)
2654{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002655 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002656 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002657 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002658 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002659 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002660 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002661 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002662 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002663 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002664 for (i = 0; i < channels; i++)
2665 video_unregister_device(&dev->channel[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002666 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002667 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2668 wake_up(&dev->fw_data->wait_fw);
2669 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002670 dev->channel[i].setmode_ready = 1;
2671 wake_up(&dev->channel[i].wait_setmode);
2672 dev->channel[i].vidstatus_ready = 1;
2673 wake_up(&dev->channel[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002674 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002675 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002676 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002677 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002678}
2679
2680static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002681 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002682 .probe = s2255_probe,
2683 .disconnect = s2255_disconnect,
2684 .id_table = s2255_table,
2685};
2686
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002687module_usb_driver(s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002688
2689MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2690MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2691MODULE_LICENSE("GPL");
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03002692MODULE_VERSION(S2255_VERSION);