blob: 5b9dce85645c351220330db9a14b0f39cf628763 [file] [log] [blame]
Dean Anderson38f993a2008-06-26 23:15:51 -03001/*
2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
3 *
Dean Anderson4de39f52010-03-03 19:39:19 -03004 * Copyright (C) 2007-2010 by Sensoray Company Inc.
Dean Anderson38f993a2008-06-26 23:15:51 -03005 * Dean Anderson
6 *
7 * Some video buffer code based on vivi driver:
8 *
9 * Sensoray 2255 device supports 4 simultaneous channels.
10 * The channels are not "crossbar" inputs, they are physically
11 * attached to separate video decoders.
12 *
13 * Because of USB2.0 bandwidth limitations. There is only a
14 * certain amount of data which may be transferred at one time.
15 *
16 * Example maximum bandwidth utilization:
17 *
18 * -full size, color mode YUYV or YUV422P: 2 channels at once
19 *
20 * -full or half size Grey scale: all 4 channels at once
21 *
22 * -half size, color mode YUYV or YUV422P: all 4 channels at once
23 *
24 * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
25 * at once.
26 * (TODO: Incorporate videodev2 frame rate(FR) enumeration,
27 * which is currently experimental.)
28 *
29 * This program is free software; you can redistribute it and/or modify
30 * it under the terms of the GNU General Public License as published by
31 * the Free Software Foundation; either version 2 of the License, or
32 * (at your option) any later version.
33 *
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
38 *
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42 */
43
44#include <linux/module.h>
45#include <linux/firmware.h>
46#include <linux/kernel.h>
47#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090048#include <linux/slab.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030049#include <linux/videodev2.h>
50#include <linux/version.h>
Hans Verkuilfeb75f02008-07-27 06:30:21 -030051#include <linux/mm.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030052#include <media/videobuf-vmalloc.h>
53#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030054#include <media/v4l2-device.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030055#include <media/v4l2-ioctl.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030056#include <linux/vmalloc.h>
57#include <linux/usb.h>
58
Dean Anderson85b85482010-04-08 23:51:17 -030059#define S2255_MAJOR_VERSION 1
sensoray-dev752eb7a2011-01-19 17:41:45 -030060#define S2255_MINOR_VERSION 21
Dean Anderson85b85482010-04-08 23:51:17 -030061#define S2255_RELEASE 0
62#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
63 S2255_MINOR_VERSION, \
64 S2255_RELEASE)
Dean Anderson38f993a2008-06-26 23:15:51 -030065#define FIRMWARE_FILE_NAME "f2255usb.bin"
66
Dean Anderson22b88d42008-08-29 15:33:19 -030067/* default JPEG quality */
68#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030069/* vendor request in */
70#define S2255_VR_IN 0
71/* vendor request out */
72#define S2255_VR_OUT 1
73/* firmware query */
74#define S2255_VR_FW 0x30
75/* USB endpoint number for configuring the device */
76#define S2255_CONFIG_EP 2
77/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030078#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030079/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030080#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson38f993a2008-06-26 23:15:51 -030081#define S2255_DEF_BUFS 16
Dean Anderson14d96262008-08-25 13:58:55 -030082#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030083#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030084#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
85#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
86#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
87#define S2255_RESPONSE_FW cpu_to_le32(0x10)
88#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030089#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030090#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030091#define SYS_FRAMES 4
92/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030093#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
94#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030095#define LINE_SZ_4CIFS_NTSC 640
96#define LINE_SZ_2CIFS_NTSC 640
97#define LINE_SZ_1CIFS_NTSC 320
98#define LINE_SZ_4CIFS_PAL 704
99#define LINE_SZ_2CIFS_PAL 704
100#define LINE_SZ_1CIFS_PAL 352
101#define NUM_LINES_4CIFS_NTSC 240
102#define NUM_LINES_2CIFS_NTSC 240
103#define NUM_LINES_1CIFS_NTSC 240
104#define NUM_LINES_4CIFS_PAL 288
105#define NUM_LINES_2CIFS_PAL 288
106#define NUM_LINES_1CIFS_PAL 288
107#define LINE_SZ_DEF 640
108#define NUM_LINES_DEF 240
109
110
111/* predefined settings */
112#define FORMAT_NTSC 1
113#define FORMAT_PAL 2
114
115#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
116#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
117#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300118/* SCALE_4CIFSI is the 2 fields interpolated into one */
119#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300120
121#define COLOR_YUVPL 1 /* YUV planar */
122#define COLOR_YUVPK 2 /* YUV packed */
123#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300124#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300125
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300126#define MASK_COLOR 0x000000ff
127#define MASK_JPG_QUALITY 0x0000ff00
128#define MASK_INPUT_TYPE 0x000f0000
Dean Anderson38f993a2008-06-26 23:15:51 -0300129/* frame decimation. Not implemented by V4L yet(experimental in V4L) */
130#define FDEC_1 1 /* capture every frame. default */
131#define FDEC_2 2 /* capture every 2nd frame */
132#define FDEC_3 3 /* capture every 3rd frame */
133#define FDEC_5 5 /* capture every 5th frame */
134
135/*-------------------------------------------------------
136 * Default mode parameters.
137 *-------------------------------------------------------*/
138#define DEF_SCALE SCALE_4CIFS
139#define DEF_COLOR COLOR_YUVPL
140#define DEF_FDEC FDEC_1
141#define DEF_BRIGHT 0
142#define DEF_CONTRAST 0x5c
143#define DEF_SATURATION 0x80
144#define DEF_HUE 0
145
146/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300147#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
148#define CMD_2255 cpu_to_le32(0xc2255000)
149#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
150#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
151#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
152#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300153
154struct s2255_mode {
155 u32 format; /* input video format (NTSC, PAL) */
156 u32 scale; /* output video scale */
157 u32 color; /* output video color format */
158 u32 fdec; /* frame decimation */
159 u32 bright; /* brightness */
160 u32 contrast; /* contrast */
161 u32 saturation; /* saturation */
162 u32 hue; /* hue (NTSC only)*/
163 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
164 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
165 u32 restart; /* if DSP requires restart */
166};
167
Dean Anderson14d96262008-08-25 13:58:55 -0300168
169#define S2255_READ_IDLE 0
170#define S2255_READ_FRAME 1
171
Dean Anderson38f993a2008-06-26 23:15:51 -0300172/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300173struct s2255_framei {
174 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300175 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300176 void *lpvbits; /* image data */
177 unsigned long cur_size; /* current data copied to it */
178};
179
180/* image buffer structure */
181struct s2255_bufferi {
182 unsigned long dwFrames; /* number of frames in buffer */
183 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
184};
185
186#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
187 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300188 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300189
190struct s2255_dmaqueue {
191 struct list_head active;
Dean Anderson38f993a2008-06-26 23:15:51 -0300192 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300193};
194
195/* for firmware loading, fw_state */
196#define S2255_FW_NOTLOADED 0
197#define S2255_FW_LOADED_DSPWAIT 1
198#define S2255_FW_SUCCESS 2
199#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300200#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300201#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300202/* 2255 read states */
203#define S2255_READ_IDLE 0
204#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300205struct s2255_fw {
206 int fw_loaded;
207 int fw_size;
208 struct urb *fw_urb;
209 atomic_t fw_state;
210 void *pfw_data;
211 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300212 const struct firmware *fw;
213};
214
215struct s2255_pipeinfo {
216 u32 max_transfer_size;
217 u32 cur_transfer_size;
218 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300219 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300220 void *stream_urb;
221 void *dev; /* back pointer to s2255_dev struct*/
222 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300223 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300224};
225
226struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300227struct s2255_dev;
228
229struct s2255_channel {
230 struct video_device vdev;
231 int resources;
232 struct s2255_dmaqueue vidq;
233 struct s2255_bufferi buffer;
234 struct s2255_mode mode;
235 /* jpeg compression */
236 struct v4l2_jpegcompression jc;
237 /* capture parameters (for high quality mode full size) */
238 struct v4l2_captureparm cap_parm;
239 int cur_frame;
240 int last_frame;
241
242 int b_acquire;
243 /* allocated image size */
244 unsigned long req_image_size;
245 /* received packet size */
246 unsigned long pkt_size;
247 int bad_payload;
248 unsigned long frame_count;
249 /* if JPEG image */
250 int jpg_size;
251 /* if channel configured to default state */
252 int configured;
253 wait_queue_head_t wait_setmode;
254 int setmode_ready;
255 /* video status items */
256 int vidstatus;
257 wait_queue_head_t wait_vidstatus;
258 int vidstatus_ready;
259 unsigned int width;
260 unsigned int height;
261 const struct s2255_fmt *fmt;
262 int idx; /* channel number on device, 0-3 */
263};
264
Dean Anderson38f993a2008-06-26 23:15:51 -0300265
266struct s2255_dev {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300267 struct s2255_channel channel[MAX_CHANNELS];
Dean Anderson65c6edb2010-04-20 17:21:32 -0300268 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300269 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300270 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300271 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson38f993a2008-06-26 23:15:51 -0300272 struct mutex open_lock;
Dean Anderson38f993a2008-06-26 23:15:51 -0300273 struct usb_device *udev;
274 struct usb_interface *interface;
275 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300276 struct timer_list timer;
277 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300278 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300279 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300280 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300281 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300282 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300283 /* dsp firmware version (f2255usb.bin) */
284 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300285 u16 pid; /* product id */
Dean Anderson38f993a2008-06-26 23:15:51 -0300286};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300287
Dean Anderson65c6edb2010-04-20 17:21:32 -0300288static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
289{
290 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
291}
Dean Anderson38f993a2008-06-26 23:15:51 -0300292
293struct s2255_fmt {
294 char *name;
295 u32 fourcc;
296 int depth;
297};
298
299/* buffer for one video frame */
300struct s2255_buffer {
301 /* common v4l buffer stuff -- must be first */
302 struct videobuf_buffer vb;
303 const struct s2255_fmt *fmt;
304};
305
306struct s2255_fh {
307 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300308 struct videobuf_queue vb_vidq;
309 enum v4l2_buf_type type;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300310 struct s2255_channel *channel;
311 int resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300312};
313
Dean Andersonabce21f2009-04-23 16:04:41 -0300314/* current cypress EEPROM firmware version */
sensoray-dev752eb7a2011-01-19 17:41:45 -0300315#define S2255_CUR_USB_FWVER ((3 << 8) | 11)
Dean Anderson4de39f52010-03-03 19:39:19 -0300316/* current DSP FW version */
sensoray-dev752eb7a2011-01-19 17:41:45 -0300317#define S2255_CUR_DSP_FWVER 10102
Dean Anderson4de39f52010-03-03 19:39:19 -0300318/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300319#define S2255_MIN_DSP_STATUS 5
320#define S2255_MIN_DSP_COLORFILTER 8
Dean Anderson38f993a2008-06-26 23:15:51 -0300321#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300322
323/* private V4L2 controls */
324
325/*
326 * The following chart displays how COLORFILTER should be set
327 * =========================================================
328 * = fourcc = COLORFILTER =
329 * = ===============================
330 * = = 0 = 1 =
331 * =========================================================
332 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
333 * = = s-video or = composite =
334 * = = B/W camera = input =
335 * =========================================================
336 * = other = color, svideo = color, =
337 * = = = composite =
338 * =========================================================
339 *
340 * Notes:
341 * channels 0-3 on 2255 are composite
342 * channels 0-1 on 2257 are composite, 2-3 are s-video
343 * If COLORFILTER is 0 with a composite color camera connected,
344 * the output will appear monochrome but hatching
345 * will occur.
346 * COLORFILTER is different from "color killer" and "color effects"
347 * for reasons above.
348 */
349#define S2255_V4L2_YC_ON 1
350#define S2255_V4L2_YC_OFF 0
351#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
352
Dean Anderson38f993a2008-06-26 23:15:51 -0300353/* frame prefix size (sent once every frame) */
354#define PREFIX_SIZE 512
355
356/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300357static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300358
Dean Anderson38f993a2008-06-26 23:15:51 -0300359static int debug;
360static int *s2255_debug = &debug;
361
362static int s2255_start_readpipe(struct s2255_dev *dev);
363static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300364static int s2255_start_acquire(struct s2255_channel *channel);
365static int s2255_stop_acquire(struct s2255_channel *channel);
366static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
367 int jpgsize);
368static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300369static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300370static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300371static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300372static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
373 u16 index, u16 value, void *buf,
374 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300375
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300376/* dev_err macro with driver name */
377#define S2255_DRIVER_NAME "s2255"
378#define s2255_dev_err(dev, fmt, arg...) \
379 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
380
Dean Anderson38f993a2008-06-26 23:15:51 -0300381#define dprintk(level, fmt, arg...) \
382 do { \
383 if (*s2255_debug >= (level)) { \
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300384 printk(KERN_DEBUG S2255_DRIVER_NAME \
385 ": " fmt, ##arg); \
Dean Anderson38f993a2008-06-26 23:15:51 -0300386 } \
387 } while (0)
388
Dean Anderson38f993a2008-06-26 23:15:51 -0300389static struct usb_driver s2255_driver;
390
Dean Anderson38f993a2008-06-26 23:15:51 -0300391/* Declare static vars that will be used as parameters */
392static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
393
394/* start video number */
395static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
396
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300397/* Enable jpeg capture. */
398static int jpeg_enable = 1;
399
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300400module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300401MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300402module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300403MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300404module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300405MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300406module_param(jpeg_enable, int, 0644);
407MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
Dean Anderson38f993a2008-06-26 23:15:51 -0300408
409/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300410#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300411static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300412 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
413 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300414 { } /* Terminating entry */
415};
416MODULE_DEVICE_TABLE(usb, s2255_table);
417
Dean Anderson38f993a2008-06-26 23:15:51 -0300418#define BUFFER_TIMEOUT msecs_to_jiffies(400)
419
Dean Anderson38f993a2008-06-26 23:15:51 -0300420/* image formats. */
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300421/* JPEG formats must be defined last to support jpeg_enable parameter */
Dean Anderson38f993a2008-06-26 23:15:51 -0300422static const struct s2255_fmt formats[] = {
423 {
424 .name = "4:2:2, planar, YUV422P",
425 .fourcc = V4L2_PIX_FMT_YUV422P,
426 .depth = 16
427
428 }, {
429 .name = "4:2:2, packed, YUYV",
430 .fourcc = V4L2_PIX_FMT_YUYV,
431 .depth = 16
432
433 }, {
434 .name = "4:2:2, packed, UYVY",
435 .fourcc = V4L2_PIX_FMT_UYVY,
436 .depth = 16
437 }, {
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300438 .name = "8bpp GREY",
439 .fourcc = V4L2_PIX_FMT_GREY,
440 .depth = 8
441 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300442 .name = "JPG",
443 .fourcc = V4L2_PIX_FMT_JPEG,
444 .depth = 24
445 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300446 .name = "MJPG",
447 .fourcc = V4L2_PIX_FMT_MJPEG,
448 .depth = 24
Dean Anderson38f993a2008-06-26 23:15:51 -0300449 }
450};
451
452static int norm_maxw(struct video_device *vdev)
453{
454 return (vdev->current_norm & V4L2_STD_NTSC) ?
455 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
456}
457
458static int norm_maxh(struct video_device *vdev)
459{
460 return (vdev->current_norm & V4L2_STD_NTSC) ?
461 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
462}
463
464static int norm_minw(struct video_device *vdev)
465{
466 return (vdev->current_norm & V4L2_STD_NTSC) ?
467 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
468}
469
470static int norm_minh(struct video_device *vdev)
471{
472 return (vdev->current_norm & V4L2_STD_NTSC) ?
473 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
474}
475
476
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300477/*
478 * TODO: fixme: move YUV reordering to hardware
479 * converts 2255 planar format to yuyv or uyvy
480 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300481static void planar422p_to_yuv_packed(const unsigned char *in,
482 unsigned char *out,
483 int width, int height,
484 int fmt)
485{
486 unsigned char *pY;
487 unsigned char *pCb;
488 unsigned char *pCr;
489 unsigned long size = height * width;
490 unsigned int i;
491 pY = (unsigned char *)in;
492 pCr = (unsigned char *)in + height * width;
493 pCb = (unsigned char *)in + height * width + (height * width / 2);
494 for (i = 0; i < size * 2; i += 4) {
495 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
496 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
497 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
498 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
499 }
500 return;
501}
502
Hans Verkuild45b9b82008-09-04 03:33:43 -0300503static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300504{
sensoray-dev752eb7a2011-01-19 17:41:45 -0300505 s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b01, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300506 msleep(10);
507 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300508 msleep(600);
509 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300510 return;
511}
Dean Anderson38f993a2008-06-26 23:15:51 -0300512
513/* kickstarts the firmware loading. from probe
514 */
515static void s2255_timer(unsigned long user_data)
516{
517 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson85b85482010-04-08 23:51:17 -0300518 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300519 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
520 printk(KERN_ERR "s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300521 atomic_set(&data->fw_state, S2255_FW_FAILED);
522 /* wake up anything waiting for the firmware */
523 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300524 return;
525 }
526}
527
Dean Anderson38f993a2008-06-26 23:15:51 -0300528
529/* this loads the firmware asynchronously.
530 Originally this was done synchroously in probe.
531 But it is better to load it asynchronously here than block
532 inside the probe function. Blocking inside probe affects boot time.
533 FW loading is triggered by the timer in the probe function
534*/
535static void s2255_fwchunk_complete(struct urb *urb)
536{
537 struct s2255_fw *data = urb->context;
538 struct usb_device *udev = urb->dev;
539 int len;
Dean Anderson85b85482010-04-08 23:51:17 -0300540 dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
Dean Anderson38f993a2008-06-26 23:15:51 -0300541 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300542 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300543 atomic_set(&data->fw_state, S2255_FW_FAILED);
544 /* wake up anything waiting for the firmware */
545 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300546 return;
547 }
548 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300549 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300550 atomic_set(&data->fw_state, S2255_FW_FAILED);
551 /* wake up anything waiting for the firmware */
552 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300553 return;
554 }
555#define CHUNK_SIZE 512
556 /* all USB transfers must be done with continuous kernel memory.
557 can't allocate more than 128k in current linux kernel, so
558 upload the firmware in chunks
559 */
560 if (data->fw_loaded < data->fw_size) {
561 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
562 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
563
564 if (len < CHUNK_SIZE)
565 memset(data->pfw_data, 0, CHUNK_SIZE);
566
567 dprintk(100, "completed len %d, loaded %d \n", len,
568 data->fw_loaded);
569
570 memcpy(data->pfw_data,
571 (char *) data->fw->data + data->fw_loaded, len);
572
573 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
574 data->pfw_data, CHUNK_SIZE,
575 s2255_fwchunk_complete, data);
576 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
577 dev_err(&udev->dev, "failed submit URB\n");
578 atomic_set(&data->fw_state, S2255_FW_FAILED);
579 /* wake up anything waiting for the firmware */
580 wake_up(&data->wait_fw);
581 return;
582 }
583 data->fw_loaded += len;
584 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300585 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson85b85482010-04-08 23:51:17 -0300586 dprintk(100, "%s: firmware upload complete\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300587 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300588 return;
589
590}
591
Dean Andersonfe85ce92010-06-01 19:12:07 -0300592static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300593{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300594 struct s2255_dmaqueue *dma_q = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300595 struct s2255_buffer *buf;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300596 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300597 unsigned long flags = 0;
598 int rc = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300599 spin_lock_irqsave(&dev->slock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300600 if (list_empty(&dma_q->active)) {
601 dprintk(1, "No active queue to serve\n");
602 rc = -1;
603 goto unlock;
604 }
605 buf = list_entry(dma_q->active.next,
606 struct s2255_buffer, vb.queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300607 list_del(&buf->vb.queue);
608 do_gettimeofday(&buf->vb.ts);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300609 s2255_fillbuff(channel, buf, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300610 wake_up(&buf->vb.done);
Dean Anderson85b85482010-04-08 23:51:17 -0300611 dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
Dean Anderson38f993a2008-06-26 23:15:51 -0300612unlock:
613 spin_unlock_irqrestore(&dev->slock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300614 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300615}
616
Dean Anderson38f993a2008-06-26 23:15:51 -0300617static const struct s2255_fmt *format_by_fourcc(int fourcc)
618{
619 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300620 for (i = 0; i < ARRAY_SIZE(formats); i++) {
621 if (-1 == formats[i].fourcc)
622 continue;
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300623 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
624 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
625 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300626 if (formats[i].fourcc == fourcc)
627 return formats + i;
628 }
629 return NULL;
630}
631
Dean Anderson38f993a2008-06-26 23:15:51 -0300632/* video buffer vmalloc implementation based partly on VIVI driver which is
633 * Copyright (c) 2006 by
634 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
635 * Ted Walther <ted--a.t--enumera.com>
636 * John Sokol <sokol--a.t--videotechnology.com>
637 * http://v4l.videotechnology.com/
638 *
639 */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300640static void s2255_fillbuff(struct s2255_channel *channel,
641 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300642{
643 int pos = 0;
644 struct timeval ts;
645 const char *tmpbuf;
646 char *vbuf = videobuf_to_vmalloc(&buf->vb);
647 unsigned long last_frame;
648 struct s2255_framei *frm;
649
650 if (!vbuf)
651 return;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300652 last_frame = channel->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300653 if (last_frame != -1) {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300654 frm = &channel->buffer.frame[last_frame];
Dean Anderson38f993a2008-06-26 23:15:51 -0300655 tmpbuf =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300656 (const char *)channel->buffer.frame[last_frame].lpvbits;
Dean Anderson38f993a2008-06-26 23:15:51 -0300657 switch (buf->fmt->fourcc) {
658 case V4L2_PIX_FMT_YUYV:
659 case V4L2_PIX_FMT_UYVY:
660 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
661 vbuf, buf->vb.width,
662 buf->vb.height,
663 buf->fmt->fourcc);
664 break;
665 case V4L2_PIX_FMT_GREY:
666 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
667 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300668 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300669 case V4L2_PIX_FMT_MJPEG:
Dean Anderson14d96262008-08-25 13:58:55 -0300670 buf->vb.size = jpgsize;
671 memcpy(vbuf, tmpbuf, buf->vb.size);
672 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300673 case V4L2_PIX_FMT_YUV422P:
674 memcpy(vbuf, tmpbuf,
675 buf->vb.width * buf->vb.height * 2);
676 break;
677 default:
678 printk(KERN_DEBUG "s2255: unknown format?\n");
679 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300680 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300681 } else {
682 printk(KERN_ERR "s2255: =======no frame\n");
683 return;
684
685 }
686 dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
687 (unsigned long)vbuf, pos);
688 /* tell v4l buffer was filled */
689
Dean Andersonfe85ce92010-06-01 19:12:07 -0300690 buf->vb.field_count = channel->frame_count * 2;
Dean Anderson38f993a2008-06-26 23:15:51 -0300691 do_gettimeofday(&ts);
692 buf->vb.ts = ts;
693 buf->vb.state = VIDEOBUF_DONE;
694}
695
696
697/* ------------------------------------------------------------------
698 Videobuf operations
699 ------------------------------------------------------------------*/
700
701static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
702 unsigned int *size)
703{
704 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300705 struct s2255_channel *channel = fh->channel;
706 *size = channel->width * channel->height * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300707
708 if (0 == *count)
709 *count = S2255_DEF_BUFS;
710
Andreas Bombedab7e312010-03-21 16:02:45 -0300711 if (*size * *count > vid_limit * 1024 * 1024)
712 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300713
714 return 0;
715}
716
717static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
718{
719 dprintk(4, "%s\n", __func__);
720
Dean Anderson38f993a2008-06-26 23:15:51 -0300721 videobuf_vmalloc_free(&buf->vb);
722 buf->vb.state = VIDEOBUF_NEEDS_INIT;
723}
724
725static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
726 enum v4l2_field field)
727{
728 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300729 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300730 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
731 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300732 int w = channel->width;
733 int h = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300734 dprintk(4, "%s, field=%d\n", __func__, field);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300735 if (channel->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300736 return -EINVAL;
737
Dean Andersonfe85ce92010-06-01 19:12:07 -0300738 if ((w < norm_minw(&channel->vdev)) ||
739 (w > norm_maxw(&channel->vdev)) ||
740 (h < norm_minh(&channel->vdev)) ||
741 (h > norm_maxh(&channel->vdev))) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300742 dprintk(4, "invalid buffer prepare\n");
743 return -EINVAL;
744 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300745 buf->vb.size = w * h * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300746 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
747 dprintk(4, "invalid buffer prepare\n");
748 return -EINVAL;
749 }
750
Dean Andersonfe85ce92010-06-01 19:12:07 -0300751 buf->fmt = channel->fmt;
752 buf->vb.width = w;
753 buf->vb.height = h;
Dean Anderson38f993a2008-06-26 23:15:51 -0300754 buf->vb.field = field;
755
Dean Anderson38f993a2008-06-26 23:15:51 -0300756 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
757 rc = videobuf_iolock(vq, &buf->vb, NULL);
758 if (rc < 0)
759 goto fail;
760 }
761
762 buf->vb.state = VIDEOBUF_PREPARED;
763 return 0;
764fail:
765 free_buffer(vq, buf);
766 return rc;
767}
768
769static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
770{
771 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
772 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300773 struct s2255_channel *channel = fh->channel;
774 struct s2255_dmaqueue *vidq = &channel->vidq;
Dean Anderson38f993a2008-06-26 23:15:51 -0300775 dprintk(1, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300776 buf->vb.state = VIDEOBUF_QUEUED;
777 list_add_tail(&buf->vb.queue, &vidq->active);
778}
779
780static void buffer_release(struct videobuf_queue *vq,
781 struct videobuf_buffer *vb)
782{
783 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
784 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300785 dprintk(4, "%s %d\n", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -0300786 free_buffer(vq, buf);
787}
788
789static struct videobuf_queue_ops s2255_video_qops = {
790 .buf_setup = buffer_setup,
791 .buf_prepare = buffer_prepare,
792 .buf_queue = buffer_queue,
793 .buf_release = buffer_release,
794};
795
796
Dean Andersonfe85ce92010-06-01 19:12:07 -0300797static int res_get(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300798{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300799 struct s2255_channel *channel = fh->channel;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300800 /* is it free? */
801 if (channel->resources)
802 return 0; /* no, someone else uses it */
Dean Anderson38f993a2008-06-26 23:15:51 -0300803 /* it's free, grab it */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300804 channel->resources = 1;
805 fh->resources = 1;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300806 dprintk(1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300807 return 1;
808}
809
Dean Andersonfe85ce92010-06-01 19:12:07 -0300810static int res_locked(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300811{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300812 return fh->channel->resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300813}
814
Dean Andersonf78d92c2008-07-22 14:43:27 -0300815static int res_check(struct s2255_fh *fh)
816{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300817 return fh->resources;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300818}
819
820
Dean Andersonfe85ce92010-06-01 19:12:07 -0300821static void res_free(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300822{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300823 struct s2255_channel *channel = fh->channel;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300824 channel->resources = 0;
825 fh->resources = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300826 dprintk(1, "res: put\n");
827}
828
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300829static int vidioc_querymenu(struct file *file, void *priv,
830 struct v4l2_querymenu *qmenu)
831{
832 static const char *colorfilter[] = {
833 "Off",
834 "On",
835 NULL
836 };
837 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
838 int i;
839 const char **menu_items = colorfilter;
840 for (i = 0; i < qmenu->index && menu_items[i]; i++)
841 ; /* do nothing (from v4l2-common.c) */
842 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
843 return -EINVAL;
844 strlcpy(qmenu->name, menu_items[qmenu->index],
845 sizeof(qmenu->name));
846 return 0;
847 }
848 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
849}
850
Dean Anderson38f993a2008-06-26 23:15:51 -0300851static int vidioc_querycap(struct file *file, void *priv,
852 struct v4l2_capability *cap)
853{
854 struct s2255_fh *fh = file->private_data;
855 struct s2255_dev *dev = fh->dev;
856 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
857 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300858 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Dean Anderson38f993a2008-06-26 23:15:51 -0300859 cap->version = S2255_VERSION;
860 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
861 return 0;
862}
863
864static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
865 struct v4l2_fmtdesc *f)
866{
867 int index = 0;
868 if (f)
869 index = f->index;
870
871 if (index >= ARRAY_SIZE(formats))
872 return -EINVAL;
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300873 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
874 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
875 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300876 dprintk(4, "name %s\n", formats[index].name);
877 strlcpy(f->description, formats[index].name, sizeof(f->description));
878 f->pixelformat = formats[index].fourcc;
879 return 0;
880}
881
882static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
883 struct v4l2_format *f)
884{
885 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300886 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300887
Dean Andersonfe85ce92010-06-01 19:12:07 -0300888 f->fmt.pix.width = channel->width;
889 f->fmt.pix.height = channel->height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300890 f->fmt.pix.field = fh->vb_vidq.field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300891 f->fmt.pix.pixelformat = channel->fmt->fourcc;
892 f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300893 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300894 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300895}
896
897static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
898 struct v4l2_format *f)
899{
900 const struct s2255_fmt *fmt;
901 enum v4l2_field field;
902 int b_any_field = 0;
903 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300904 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300905 int is_ntsc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300906 is_ntsc =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300907 (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300908
909 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
910
911 if (fmt == NULL)
912 return -EINVAL;
913
914 field = f->fmt.pix.field;
915 if (field == V4L2_FIELD_ANY)
916 b_any_field = 1;
917
Dean Anderson85b85482010-04-08 23:51:17 -0300918 dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
919 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300920 if (is_ntsc) {
921 /* NTSC */
922 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
923 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
924 if (b_any_field) {
925 field = V4L2_FIELD_SEQ_TB;
926 } else if (!((field == V4L2_FIELD_INTERLACED) ||
927 (field == V4L2_FIELD_SEQ_TB) ||
928 (field == V4L2_FIELD_INTERLACED_TB))) {
929 dprintk(1, "unsupported field setting\n");
930 return -EINVAL;
931 }
932 } else {
933 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
934 if (b_any_field) {
935 field = V4L2_FIELD_TOP;
936 } else if (!((field == V4L2_FIELD_TOP) ||
937 (field == V4L2_FIELD_BOTTOM))) {
938 dprintk(1, "unsupported field setting\n");
939 return -EINVAL;
940 }
941
942 }
943 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
944 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
945 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
946 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
947 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
948 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
949 else
950 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
951 } else {
952 /* PAL */
953 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
954 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
955 if (b_any_field) {
956 field = V4L2_FIELD_SEQ_TB;
957 } else if (!((field == V4L2_FIELD_INTERLACED) ||
958 (field == V4L2_FIELD_SEQ_TB) ||
959 (field == V4L2_FIELD_INTERLACED_TB))) {
960 dprintk(1, "unsupported field setting\n");
961 return -EINVAL;
962 }
963 } else {
964 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
965 if (b_any_field) {
966 field = V4L2_FIELD_TOP;
967 } else if (!((field == V4L2_FIELD_TOP) ||
968 (field == V4L2_FIELD_BOTTOM))) {
969 dprintk(1, "unsupported field setting\n");
970 return -EINVAL;
971 }
972 }
973 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300974 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
975 field = V4L2_FIELD_SEQ_TB;
976 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300977 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
978 field = V4L2_FIELD_TOP;
979 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300980 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
981 field = V4L2_FIELD_TOP;
982 } else {
Dean Anderson38f993a2008-06-26 23:15:51 -0300983 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
984 field = V4L2_FIELD_TOP;
985 }
986 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300987 f->fmt.pix.field = field;
988 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
989 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Dean Anderson85b85482010-04-08 23:51:17 -0300990 dprintk(50, "%s: set width %d height %d field %d\n", __func__,
991 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300992 return 0;
993}
994
995static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
996 struct v4l2_format *f)
997{
998 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300999 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001000 const struct s2255_fmt *fmt;
1001 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001002 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001003 int ret;
1004 int norm;
1005
1006 ret = vidioc_try_fmt_vid_cap(file, fh, f);
1007
1008 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001009 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001010
1011 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1012
1013 if (fmt == NULL)
1014 return -EINVAL;
1015
1016 mutex_lock(&q->vb_lock);
1017
1018 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1019 dprintk(1, "queue busy\n");
1020 ret = -EBUSY;
1021 goto out_s_fmt;
1022 }
1023
Dean Andersonfe85ce92010-06-01 19:12:07 -03001024 if (res_locked(fh)) {
Dean Anderson85b85482010-04-08 23:51:17 -03001025 dprintk(1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001026 ret = -EBUSY;
1027 goto out_s_fmt;
1028 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001029 mode = channel->mode;
1030 channel->fmt = fmt;
1031 channel->width = f->fmt.pix.width;
1032 channel->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -03001033 fh->vb_vidq.field = f->fmt.pix.field;
1034 fh->type = f->type;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001035 norm = norm_minw(&channel->vdev);
1036 if (channel->width > norm_minw(&channel->vdev)) {
1037 if (channel->height > norm_minh(&channel->vdev)) {
1038 if (channel->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -03001039 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001040 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -03001041 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001042 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -03001043 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001044 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001045
1046 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001047 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001048 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001049 /* color mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001050 switch (channel->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001051 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001052 mode.color &= ~MASK_COLOR;
1053 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -03001054 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001055 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -03001056 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001057 mode.color &= ~MASK_COLOR;
1058 mode.color |= COLOR_JPG;
1059 mode.color |= (channel->jc.quality << 8);
Dean Anderson14d96262008-08-25 13:58:55 -03001060 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001061 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001062 mode.color &= ~MASK_COLOR;
1063 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001064 break;
1065 case V4L2_PIX_FMT_YUYV:
1066 case V4L2_PIX_FMT_UYVY:
1067 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001068 mode.color &= ~MASK_COLOR;
1069 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -03001070 break;
1071 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001072 if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
1073 mode.restart = 1;
1074 else if (mode.scale != channel->mode.scale)
1075 mode.restart = 1;
1076 else if (mode.format != channel->mode.format)
1077 mode.restart = 1;
1078 channel->mode = mode;
1079 (void) s2255_set_mode(channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001080 ret = 0;
1081out_s_fmt:
1082 mutex_unlock(&q->vb_lock);
1083 return ret;
1084}
1085
1086static int vidioc_reqbufs(struct file *file, void *priv,
1087 struct v4l2_requestbuffers *p)
1088{
1089 int rc;
1090 struct s2255_fh *fh = priv;
1091 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1092 return rc;
1093}
1094
1095static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1096{
1097 int rc;
1098 struct s2255_fh *fh = priv;
1099 rc = videobuf_querybuf(&fh->vb_vidq, p);
1100 return rc;
1101}
1102
1103static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1104{
1105 int rc;
1106 struct s2255_fh *fh = priv;
1107 rc = videobuf_qbuf(&fh->vb_vidq, p);
1108 return rc;
1109}
1110
1111static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1112{
1113 int rc;
1114 struct s2255_fh *fh = priv;
1115 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1116 return rc;
1117}
1118
Dean Anderson38f993a2008-06-26 23:15:51 -03001119/* write to the configuration pipe, synchronously */
1120static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1121 int size)
1122{
1123 int pipe;
1124 int done;
1125 long retval = -1;
1126 if (udev) {
1127 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1128 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1129 }
1130 return retval;
1131}
1132
1133static u32 get_transfer_size(struct s2255_mode *mode)
1134{
1135 int linesPerFrame = LINE_SZ_DEF;
1136 int pixelsPerLine = NUM_LINES_DEF;
1137 u32 outImageSize;
1138 u32 usbInSize;
1139 unsigned int mask_mult;
1140
1141 if (mode == NULL)
1142 return 0;
1143
1144 if (mode->format == FORMAT_NTSC) {
1145 switch (mode->scale) {
1146 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001147 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001148 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1149 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1150 break;
1151 case SCALE_2CIFS:
1152 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1153 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1154 break;
1155 case SCALE_1CIFS:
1156 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1157 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1158 break;
1159 default:
1160 break;
1161 }
1162 } else if (mode->format == FORMAT_PAL) {
1163 switch (mode->scale) {
1164 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001165 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001166 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1167 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1168 break;
1169 case SCALE_2CIFS:
1170 linesPerFrame = NUM_LINES_2CIFS_PAL;
1171 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1172 break;
1173 case SCALE_1CIFS:
1174 linesPerFrame = NUM_LINES_1CIFS_PAL;
1175 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1176 break;
1177 default:
1178 break;
1179 }
1180 }
1181 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001182 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001183 /* 2 bytes/pixel if not monochrome */
1184 outImageSize *= 2;
1185 }
1186
1187 /* total bytes to send including prefix and 4K padding;
1188 must be a multiple of USB_READ_SIZE */
1189 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1190 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1191 /* if size not a multiple of USB_READ_SIZE */
1192 if (usbInSize & ~mask_mult)
1193 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1194 return usbInSize;
1195}
1196
Dean Anderson85b85482010-04-08 23:51:17 -03001197static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001198{
1199 struct device *dev = &sdev->udev->dev;
1200 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001201 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1202 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001203 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001204 dev_info(dev, "------------------------------------------------\n");
1205}
1206
1207/*
1208 * set mode is the function which controls the DSP.
1209 * the restart parameter in struct s2255_mode should be set whenever
1210 * the image size could change via color format, video system or image
1211 * size.
1212 * When the restart parameter is set, we sleep for ONE frame to allow the
1213 * DSP time to get the new frame
1214 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001215static int s2255_set_mode(struct s2255_channel *channel,
Dean Anderson38f993a2008-06-26 23:15:51 -03001216 struct s2255_mode *mode)
1217{
1218 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001219 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001220 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001221 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001222 chn_rev = G_chnmap[channel->idx];
1223 dprintk(3, "%s channel: %d\n", __func__, channel->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001224 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001225 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1226 mode->color &= ~MASK_COLOR;
1227 mode->color |= COLOR_JPG;
1228 mode->color &= ~MASK_JPG_QUALITY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001229 mode->color |= (channel->jc.quality << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001230 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001231 /* save the mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001232 channel->mode = *mode;
1233 channel->req_image_size = get_transfer_size(mode);
1234 dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001235 buffer = kzalloc(512, GFP_KERNEL);
1236 if (buffer == NULL) {
1237 dev_err(&dev->udev->dev, "out of mem\n");
1238 return -ENOMEM;
1239 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001240 /* set the mode */
1241 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001242 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001243 buffer[2] = CMD_SET_MODE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001244 memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
1245 channel->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001246 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1247 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001248 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001249 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001250 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001251 if (mode->restart) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001252 wait_event_timeout(channel->wait_setmode,
1253 (channel->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001254 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001255 if (channel->setmode_ready != 1) {
Dean Anderson14d96262008-08-25 13:58:55 -03001256 printk(KERN_DEBUG "s2255: no set mode response\n");
1257 res = -EFAULT;
1258 }
1259 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001260 /* clear the restart flag */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001261 channel->mode.restart = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001262 dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001263 return res;
1264}
1265
Dean Andersonfe85ce92010-06-01 19:12:07 -03001266static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001267{
1268 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001269 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001270 u32 chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001271 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001272 chn_rev = G_chnmap[channel->idx];
1273 dprintk(4, "%s chan %d\n", __func__, channel->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001274 buffer = kzalloc(512, GFP_KERNEL);
1275 if (buffer == NULL) {
1276 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001277 return -ENOMEM;
1278 }
1279 /* form the get vid status command */
1280 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001281 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001282 buffer[2] = CMD_STATUS;
1283 *pstatus = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001284 channel->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001285 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1286 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001287 wait_event_timeout(channel->wait_vidstatus,
1288 (channel->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001289 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001290 if (channel->vidstatus_ready != 1) {
Dean Anderson4de39f52010-03-03 19:39:19 -03001291 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1292 res = -EFAULT;
1293 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001294 *pstatus = channel->vidstatus;
Dean Anderson4de39f52010-03-03 19:39:19 -03001295 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03001296 return res;
1297}
1298
Dean Anderson38f993a2008-06-26 23:15:51 -03001299static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1300{
1301 int res;
1302 struct s2255_fh *fh = priv;
1303 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001304 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001305 int j;
1306 dprintk(4, "%s\n", __func__);
1307 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1308 dev_err(&dev->udev->dev, "invalid fh type0\n");
1309 return -EINVAL;
1310 }
1311 if (i != fh->type) {
1312 dev_err(&dev->udev->dev, "invalid fh type1\n");
1313 return -EINVAL;
1314 }
1315
Dean Andersonfe85ce92010-06-01 19:12:07 -03001316 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001317 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001318 return -EBUSY;
1319 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001320 channel->last_frame = -1;
1321 channel->bad_payload = 0;
1322 channel->cur_frame = 0;
1323 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001324 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001325 channel->buffer.frame[j].ulState = S2255_READ_IDLE;
1326 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001327 }
1328 res = videobuf_streamon(&fh->vb_vidq);
1329 if (res == 0) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001330 s2255_start_acquire(channel);
1331 channel->b_acquire = 1;
1332 } else
1333 res_free(fh);
1334
Dean Anderson38f993a2008-06-26 23:15:51 -03001335 return res;
1336}
1337
1338static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1339{
Dean Anderson38f993a2008-06-26 23:15:51 -03001340 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001341 dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001342 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1343 printk(KERN_ERR "invalid fh type0\n");
1344 return -EINVAL;
1345 }
1346 if (i != fh->type) {
1347 printk(KERN_ERR "invalid type i\n");
1348 return -EINVAL;
1349 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001350 s2255_stop_acquire(fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001351 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001352 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001353 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001354}
1355
1356static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1357{
1358 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001359 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001360 struct videobuf_queue *q = &fh->vb_vidq;
1361 int ret = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001362 mutex_lock(&q->vb_lock);
1363 if (videobuf_queue_is_busy(q)) {
1364 dprintk(1, "queue busy\n");
1365 ret = -EBUSY;
1366 goto out_s_std;
1367 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001368 if (res_locked(fh)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001369 dprintk(1, "can't change standard after started\n");
1370 ret = -EBUSY;
1371 goto out_s_std;
1372 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001373 mode = fh->channel->mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001374 if (*i & V4L2_STD_NTSC) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001375 dprintk(4, "%s NTSC\n", __func__);
1376 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001377 if (mode.format != FORMAT_NTSC) {
1378 mode.restart = 1;
1379 mode.format = FORMAT_NTSC;
1380 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001381 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001382 } else if (*i & V4L2_STD_PAL) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001383 dprintk(4, "%s PAL\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001384 if (mode.format != FORMAT_PAL) {
1385 mode.restart = 1;
1386 mode.format = FORMAT_PAL;
1387 mode.fdec = FDEC_1;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001388 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001389 } else {
1390 ret = -EINVAL;
1391 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001392 if (mode.restart)
1393 s2255_set_mode(fh->channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001394out_s_std:
1395 mutex_unlock(&q->vb_lock);
1396 return ret;
1397}
1398
1399/* Sensoray 2255 is a multiple channel capture device.
1400 It does not have a "crossbar" of inputs.
1401 We use one V4L device per channel. The user must
1402 be aware that certain combinations are not allowed.
1403 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1404 at once in color(you can do full fps on 4 channels with greyscale.
1405*/
1406static int vidioc_enum_input(struct file *file, void *priv,
1407 struct v4l2_input *inp)
1408{
Dean Anderson4de39f52010-03-03 19:39:19 -03001409 struct s2255_fh *fh = priv;
1410 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001411 struct s2255_channel *channel = fh->channel;
Dean Anderson4de39f52010-03-03 19:39:19 -03001412 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001413 if (inp->index != 0)
1414 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001415 inp->type = V4L2_INPUT_TYPE_CAMERA;
1416 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001417 inp->status = 0;
1418 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1419 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001420 rc = s2255_cmd_status(fh->channel, &status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001421 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1422 if (rc == 0)
1423 inp->status = (status & 0x01) ? 0
1424 : V4L2_IN_ST_NO_SIGNAL;
1425 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001426 switch (dev->pid) {
1427 case 0x2255:
1428 default:
1429 strlcpy(inp->name, "Composite", sizeof(inp->name));
1430 break;
1431 case 0x2257:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001432 strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001433 sizeof(inp->name));
1434 break;
1435 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001436 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001437}
1438
1439static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1440{
1441 *i = 0;
1442 return 0;
1443}
1444static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1445{
1446 if (i > 0)
1447 return -EINVAL;
1448 return 0;
1449}
1450
1451/* --- controls ---------------------------------------------- */
1452static int vidioc_queryctrl(struct file *file, void *priv,
1453 struct v4l2_queryctrl *qc)
1454{
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001455 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001456 struct s2255_channel *channel = fh->channel;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001457 struct s2255_dev *dev = fh->dev;
Dean Anderson2e70db92010-03-05 14:29:09 -03001458 switch (qc->id) {
1459 case V4L2_CID_BRIGHTNESS:
1460 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1461 break;
1462 case V4L2_CID_CONTRAST:
1463 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1464 break;
1465 case V4L2_CID_SATURATION:
1466 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1467 break;
1468 case V4L2_CID_HUE:
1469 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1470 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001471 case V4L2_CID_PRIVATE_COLORFILTER:
1472 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1473 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001474 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001475 return -EINVAL;
1476 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1477 qc->type = V4L2_CTRL_TYPE_MENU;
1478 qc->minimum = 0;
1479 qc->maximum = 1;
1480 qc->step = 1;
1481 qc->default_value = 1;
1482 qc->flags = 0;
1483 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001484 default:
1485 return -EINVAL;
1486 }
1487 dprintk(4, "%s, id %d\n", __func__, qc->id);
1488 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001489}
1490
1491static int vidioc_g_ctrl(struct file *file, void *priv,
1492 struct v4l2_control *ctrl)
1493{
Dean Anderson2e70db92010-03-05 14:29:09 -03001494 struct s2255_fh *fh = priv;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001495 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001496 struct s2255_channel *channel = fh->channel;
Dean Anderson2e70db92010-03-05 14:29:09 -03001497 switch (ctrl->id) {
1498 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001499 ctrl->value = channel->mode.bright;
Dean Anderson2e70db92010-03-05 14:29:09 -03001500 break;
1501 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001502 ctrl->value = channel->mode.contrast;
Dean Anderson2e70db92010-03-05 14:29:09 -03001503 break;
1504 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001505 ctrl->value = channel->mode.saturation;
Dean Anderson2e70db92010-03-05 14:29:09 -03001506 break;
1507 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001508 ctrl->value = channel->mode.hue;
Dean Anderson2e70db92010-03-05 14:29:09 -03001509 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001510 case V4L2_CID_PRIVATE_COLORFILTER:
1511 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1512 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001513 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001514 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001515 ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001516 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001517 default:
1518 return -EINVAL;
1519 }
1520 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1521 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001522}
1523
1524static int vidioc_s_ctrl(struct file *file, void *priv,
1525 struct v4l2_control *ctrl)
1526{
Dean Anderson38f993a2008-06-26 23:15:51 -03001527 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001528 struct s2255_channel *channel = fh->channel;
1529 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
1530 struct s2255_mode mode;
1531 mode = channel->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001532 dprintk(4, "%s\n", __func__);
1533 /* update the mode to the corresponding value */
1534 switch (ctrl->id) {
1535 case V4L2_CID_BRIGHTNESS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001536 mode.bright = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001537 break;
1538 case V4L2_CID_CONTRAST:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001539 mode.contrast = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001540 break;
1541 case V4L2_CID_HUE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001542 mode.hue = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001543 break;
1544 case V4L2_CID_SATURATION:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001545 mode.saturation = ctrl->value;
Dean Anderson2e70db92010-03-05 14:29:09 -03001546 break;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001547 case V4L2_CID_PRIVATE_COLORFILTER:
1548 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1549 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001550 if ((dev->pid == 0x2257) && (channel->idx > 1))
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001551 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001552 mode.color &= ~MASK_INPUT_TYPE;
1553 mode.color |= ((ctrl->value ? 0 : 1) << 16);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001554 break;
Dean Anderson2e70db92010-03-05 14:29:09 -03001555 default:
1556 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001557 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001558 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001559 /* set mode here. Note: stream does not need restarted.
1560 some V4L programs restart stream unnecessarily
1561 after a s_crtl.
1562 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001563 s2255_set_mode(fh->channel, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001564 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001565}
1566
Dean Anderson22b88d42008-08-29 15:33:19 -03001567static int vidioc_g_jpegcomp(struct file *file, void *priv,
1568 struct v4l2_jpegcompression *jc)
1569{
1570 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001571 struct s2255_channel *channel = fh->channel;
1572 *jc = channel->jc;
Dean Anderson85b85482010-04-08 23:51:17 -03001573 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001574 return 0;
1575}
1576
1577static int vidioc_s_jpegcomp(struct file *file, void *priv,
1578 struct v4l2_jpegcompression *jc)
1579{
1580 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001581 struct s2255_channel *channel = fh->channel;
Dean Anderson22b88d42008-08-29 15:33:19 -03001582 if (jc->quality < 0 || jc->quality > 100)
1583 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001584 channel->jc.quality = jc->quality;
Dean Anderson85b85482010-04-08 23:51:17 -03001585 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001586 return 0;
1587}
Dean Anderson7d853532009-05-15 14:32:04 -03001588
1589static int vidioc_g_parm(struct file *file, void *priv,
1590 struct v4l2_streamparm *sp)
1591{
1592 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001593 __u32 def_num, def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001594 struct s2255_channel *channel = fh->channel;
Dean Anderson7d853532009-05-15 14:32:04 -03001595 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1596 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001597 memset(sp, 0, sizeof(struct v4l2_streamparm));
1598 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001599 sp->parm.capture.capturemode = channel->cap_parm.capturemode;
1600 def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1601 def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001602 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001603 switch (channel->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001604 default:
1605 case FDEC_1:
1606 sp->parm.capture.timeperframe.numerator = def_num;
1607 break;
1608 case FDEC_2:
1609 sp->parm.capture.timeperframe.numerator = def_num * 2;
1610 break;
1611 case FDEC_3:
1612 sp->parm.capture.timeperframe.numerator = def_num * 3;
1613 break;
1614 case FDEC_5:
1615 sp->parm.capture.timeperframe.numerator = def_num * 5;
1616 break;
1617 }
1618 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1619 sp->parm.capture.capturemode,
1620 sp->parm.capture.timeperframe.numerator,
1621 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001622 return 0;
1623}
1624
1625static int vidioc_s_parm(struct file *file, void *priv,
1626 struct v4l2_streamparm *sp)
1627{
1628 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001629 struct s2255_channel *channel = fh->channel;
1630 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001631 int fdec = FDEC_1;
1632 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001633 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1634 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001635 mode = channel->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001636 /* high quality capture mode requires a stream restart */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001637 if (channel->cap_parm.capturemode
1638 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001639 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001640 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1641 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001642 if (def_dem != sp->parm.capture.timeperframe.denominator)
1643 sp->parm.capture.timeperframe.numerator = def_num;
1644 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1645 sp->parm.capture.timeperframe.numerator = def_num;
1646 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1647 sp->parm.capture.timeperframe.numerator = def_num * 2;
1648 fdec = FDEC_2;
1649 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1650 sp->parm.capture.timeperframe.numerator = def_num * 3;
1651 fdec = FDEC_3;
1652 } else {
1653 sp->parm.capture.timeperframe.numerator = def_num * 5;
1654 fdec = FDEC_5;
1655 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001656 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001657 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001658 s2255_set_mode(channel, &mode);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001659 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1660 __func__,
1661 sp->parm.capture.capturemode,
1662 sp->parm.capture.timeperframe.numerator,
1663 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001664 return 0;
1665}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001666
1667static int vidioc_enum_frameintervals(struct file *file, void *priv,
1668 struct v4l2_frmivalenum *fe)
1669{
1670 int is_ntsc = 0;
1671#define NUM_FRAME_ENUMS 4
1672 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
1673 if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
1674 return -EINVAL;
1675 switch (fe->width) {
1676 case 640:
1677 if (fe->height != 240 && fe->height != 480)
1678 return -EINVAL;
1679 is_ntsc = 1;
1680 break;
1681 case 320:
1682 if (fe->height != 240)
1683 return -EINVAL;
1684 is_ntsc = 1;
1685 break;
1686 case 704:
1687 if (fe->height != 288 && fe->height != 576)
1688 return -EINVAL;
1689 break;
1690 case 352:
1691 if (fe->height != 288)
1692 return -EINVAL;
1693 break;
1694 default:
1695 return -EINVAL;
1696 }
1697 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1698 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1699 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1700 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1701 fe->discrete.denominator);
1702 return 0;
1703}
1704
Hans Verkuilbec43662008-12-30 06:58:20 -03001705static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001706{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001707 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001708 struct s2255_channel *channel = video_drvdata(file);
1709 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001710 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001711 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001712 int state;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001713 dprintk(1, "s2255: open called (dev=%s)\n",
1714 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001715 /*
1716 * open lock necessary to prevent multiple instances
1717 * of v4l-conf (or other programs) from simultaneously
1718 * reloading firmware.
1719 */
Dean Anderson38f993a2008-06-26 23:15:51 -03001720 mutex_lock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001721 state = atomic_read(&dev->fw_data->fw_state);
1722 switch (state) {
1723 case S2255_FW_DISCONNECTING:
1724 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001725 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001726 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001727 s2255_dev_err(&dev->udev->dev,
1728 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001729 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001730 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 Anderson38f993a2008-06-26 23:15:51 -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_NOTLOADED:
1740 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001741 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1742 driver loaded and then device immediately opened */
1743 printk(KERN_INFO "%s waiting for firmware load\n", __func__);
1744 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001745 ((atomic_read(&dev->fw_data->fw_state)
1746 == S2255_FW_SUCCESS) ||
1747 (atomic_read(&dev->fw_data->fw_state)
1748 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001749 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001750 /* state may have changed, re-read */
1751 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001752 break;
1753 case S2255_FW_SUCCESS:
1754 default:
1755 break;
1756 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001757 /* state may have changed in above switch statement */
1758 switch (state) {
1759 case S2255_FW_SUCCESS:
1760 break;
1761 case S2255_FW_FAILED:
1762 printk(KERN_INFO "2255 firmware load failed.\n");
Dean Andersoneb78dee2010-04-12 15:05:37 -03001763 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001764 return -ENODEV;
1765 case S2255_FW_DISCONNECTING:
1766 printk(KERN_INFO "%s: disconnecting\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001767 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001768 return -ENODEV;
1769 case S2255_FW_LOADED_DSPWAIT:
1770 case S2255_FW_NOTLOADED:
1771 printk(KERN_INFO "%s: firmware not loaded yet"
1772 "please try again later\n",
1773 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001774 /*
1775 * Timeout on firmware load means device unusable.
1776 * Set firmware failure state.
1777 * On next s2255_open the firmware will be reloaded.
1778 */
1779 atomic_set(&dev->fw_data->fw_state,
1780 S2255_FW_FAILED);
1781 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001782 return -EAGAIN;
1783 default:
1784 printk(KERN_INFO "%s: unknown state\n", __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001785 mutex_unlock(&dev->open_lock);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001786 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001787 }
Dean Andersoneb78dee2010-04-12 15:05:37 -03001788 mutex_unlock(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001789 /* allocate + initialize per filehandle data */
1790 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001791 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001792 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03001793 file->private_data = fh;
1794 fh->dev = dev;
1795 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001796 fh->channel = channel;
1797 if (!channel->configured) {
1798 /* configure channel to default state */
1799 channel->fmt = &formats[0];
1800 s2255_set_mode(channel, &channel->mode);
1801 channel->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001802 }
Dean Anderson85b85482010-04-08 23:51:17 -03001803 dprintk(1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001804 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Anderson85b85482010-04-08 23:51:17 -03001805 dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001806 (unsigned long)fh, (unsigned long)dev,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001807 (unsigned long)&channel->vidq);
Dean Anderson85b85482010-04-08 23:51:17 -03001808 dprintk(4, "%s: list_empty active=%d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001809 list_empty(&channel->vidq.active));
Dean Anderson38f993a2008-06-26 23:15:51 -03001810 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1811 NULL, &dev->slock,
1812 fh->type,
1813 V4L2_FIELD_INTERLACED,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001814 sizeof(struct s2255_buffer),
1815 fh, vdev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001816 return 0;
1817}
1818
1819
1820static unsigned int s2255_poll(struct file *file,
1821 struct poll_table_struct *wait)
1822{
1823 struct s2255_fh *fh = file->private_data;
1824 int rc;
1825 dprintk(100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001826 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1827 return POLLERR;
Dean Anderson38f993a2008-06-26 23:15:51 -03001828 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
1829 return rc;
1830}
1831
Dean Andersond62e85a2010-04-09 19:54:26 -03001832static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001833{
Dean Anderson38f993a2008-06-26 23:15:51 -03001834 /* board shutdown stops the read pipe if it is running */
1835 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001836 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001837 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001838 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001839 usb_kill_urb(dev->fw_data->fw_urb);
1840 usb_free_urb(dev->fw_data->fw_urb);
1841 dev->fw_data->fw_urb = NULL;
1842 }
Dean Andersonf78d92c2008-07-22 14:43:27 -03001843 if (dev->fw_data->fw)
1844 release_firmware(dev->fw_data->fw);
1845 kfree(dev->fw_data->pfw_data);
1846 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001847 /* reset the DSP so firmware can be reloaded next time */
1848 s2255_reset_dsppower(dev);
1849 mutex_destroy(&dev->open_lock);
1850 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001851 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001852 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001853 dprintk(1, "%s", __func__);
Dean Andersonb7732a32009-03-30 11:59:56 -03001854 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001855}
1856
Dean Andersonff7e22d2010-04-08 23:38:07 -03001857static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001858{
1859 struct s2255_fh *fh = file->private_data;
1860 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001861 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001862 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001863 if (!dev)
1864 return -ENODEV;
Dean Andersonf78d92c2008-07-22 14:43:27 -03001865 /* turn off stream */
1866 if (res_check(fh)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001867 if (channel->b_acquire)
1868 s2255_stop_acquire(fh->channel);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001869 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001870 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001871 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001872 videobuf_mmap_free(&fh->vb_vidq);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001873 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
Dean Andersonf78d92c2008-07-22 14:43:27 -03001874 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001875 return 0;
1876}
1877
1878static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1879{
1880 struct s2255_fh *fh = file->private_data;
1881 int ret;
1882
1883 if (!fh)
1884 return -ENODEV;
Dean Anderson85b85482010-04-08 23:51:17 -03001885 dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Dean Anderson38f993a2008-06-26 23:15:51 -03001886 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
Dean Anderson85b85482010-04-08 23:51:17 -03001887 dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001888 (unsigned long)vma->vm_start,
1889 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001890 return ret;
1891}
1892
Hans Verkuilbec43662008-12-30 06:58:20 -03001893static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001894 .owner = THIS_MODULE,
1895 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001896 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001897 .poll = s2255_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001898 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001899 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001900};
1901
Hans Verkuila3998102008-07-21 02:57:38 -03001902static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001903 .vidioc_querymenu = vidioc_querymenu,
Dean Anderson38f993a2008-06-26 23:15:51 -03001904 .vidioc_querycap = vidioc_querycap,
1905 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1906 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1907 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1908 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1909 .vidioc_reqbufs = vidioc_reqbufs,
1910 .vidioc_querybuf = vidioc_querybuf,
1911 .vidioc_qbuf = vidioc_qbuf,
1912 .vidioc_dqbuf = vidioc_dqbuf,
1913 .vidioc_s_std = vidioc_s_std,
1914 .vidioc_enum_input = vidioc_enum_input,
1915 .vidioc_g_input = vidioc_g_input,
1916 .vidioc_s_input = vidioc_s_input,
1917 .vidioc_queryctrl = vidioc_queryctrl,
1918 .vidioc_g_ctrl = vidioc_g_ctrl,
1919 .vidioc_s_ctrl = vidioc_s_ctrl,
1920 .vidioc_streamon = vidioc_streamon,
1921 .vidioc_streamoff = vidioc_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001922 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1923 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001924 .vidioc_s_parm = vidioc_s_parm,
1925 .vidioc_g_parm = vidioc_g_parm,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001926 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuila3998102008-07-21 02:57:38 -03001927};
1928
Dean Andersonff7e22d2010-04-08 23:38:07 -03001929static void s2255_video_device_release(struct video_device *vdev)
1930{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001931 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
1932 dprintk(4, "%s, chnls: %d \n", __func__,
1933 atomic_read(&dev->num_channels));
1934 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001935 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001936 return;
1937}
1938
Hans Verkuila3998102008-07-21 02:57:38 -03001939static struct video_device template = {
1940 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001941 .fops = &s2255_fops_v4l,
1942 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001943 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001944 .tvnorms = S2255_NORMS,
1945 .current_norm = V4L2_STD_NTSC_M,
1946};
1947
1948static int s2255_probe_v4l(struct s2255_dev *dev)
1949{
1950 int ret;
1951 int i;
1952 int cur_nr = video_nr;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001953 struct s2255_channel *channel;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001954 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1955 if (ret)
1956 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001957 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001958 /* register 4 video devices */
1959 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001960 channel = &dev->channel[i];
1961 INIT_LIST_HEAD(&channel->vidq.active);
1962 channel->vidq.dev = dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001963 /* register 4 video devices */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001964 channel->vdev = template;
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001965 channel->vdev.lock = &dev->lock;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001966 channel->vdev.v4l2_dev = &dev->v4l2_dev;
1967 video_set_drvdata(&channel->vdev, channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03001968 if (video_nr == -1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001969 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001970 VFL_TYPE_GRABBER,
1971 video_nr);
1972 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001973 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001974 VFL_TYPE_GRABBER,
1975 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001976
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001977 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001978 dev_err(&dev->udev->dev,
1979 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001980 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001981 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001982 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001983 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001984 video_device_node_name(&channel->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001985
Dean Anderson38f993a2008-06-26 23:15:51 -03001986 }
Dean Andersonabce21f2009-04-23 16:04:41 -03001987 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
1988 S2255_MAJOR_VERSION,
1989 S2255_MINOR_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001990 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001991 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001992 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001993 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001994 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001995 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001996 printk(KERN_WARNING "s2255: Not all channels available.\n");
1997 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001998}
1999
Dean Anderson38f993a2008-06-26 23:15:51 -03002000/* this function moves the usb stream read pipe data
2001 * into the system buffers.
2002 * returns 0 on success, EAGAIN if more data to process( call this
2003 * function again).
2004 *
2005 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03002006 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03002007 * bytes 4-7: channel: 0-3
2008 * bytes 8-11: payload size: size of the frame
2009 * bytes 12-payloadsize+12: frame data
2010 */
2011static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
2012{
Dean Anderson38f993a2008-06-26 23:15:51 -03002013 char *pdest;
2014 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002015 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002016 char *psrc;
2017 unsigned long copy_size;
2018 unsigned long size;
2019 s32 idx = -1;
2020 struct s2255_framei *frm;
2021 unsigned char *pdata;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002022 struct s2255_channel *channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03002023 dprintk(100, "buffer to user\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002024 channel = &dev->channel[dev->cc];
2025 idx = channel->cur_frame;
2026 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002027 if (frm->ulState == S2255_READ_IDLE) {
2028 int jj;
2029 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03002030 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03002031 int payload;
2032 /* search for marker codes */
2033 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03002034 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03002035 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03002036 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03002037 case S2255_MARKER_FRAME:
Dean Anderson14d96262008-08-25 13:58:55 -03002038 dprintk(4, "found frame marker at offset:"
2039 " %d [%x %x]\n", jj, pdata[0],
2040 pdata[1]);
2041 offset = jj + PREFIX_SIZE;
2042 bframe = 1;
2043 cc = pdword[1];
2044 if (cc >= MAX_CHANNELS) {
2045 printk(KERN_ERR
2046 "bad channel\n");
2047 return -EINVAL;
2048 }
2049 /* reverse it */
2050 dev->cc = G_chnmap[cc];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002051 channel = &dev->channel[dev->cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002052 payload = pdword[3];
Dean Andersonfe85ce92010-06-01 19:12:07 -03002053 if (payload > channel->req_image_size) {
2054 channel->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03002055 /* discard the bad frame */
2056 return -EINVAL;
2057 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002058 channel->pkt_size = payload;
2059 channel->jpg_size = pdword[4];
Dean Anderson14d96262008-08-25 13:58:55 -03002060 break;
2061 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002062
Dean Anderson14d96262008-08-25 13:58:55 -03002063 pdata += DEF_USB_BLOCK;
2064 jj += DEF_USB_BLOCK;
2065 if (pdword[1] >= MAX_CHANNELS)
2066 break;
2067 cc = G_chnmap[pdword[1]];
Roel Kluinf14a2972009-10-23 07:59:42 -03002068 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002069 break;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002070 channel = &dev->channel[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002071 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03002072 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03002073 /* check if channel valid */
2074 /* set mode ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002075 channel->setmode_ready = 1;
2076 wake_up(&channel->wait_setmode);
Dean Anderson14d96262008-08-25 13:58:55 -03002077 dprintk(5, "setmode ready %d\n", cc);
2078 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002079 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002080 dev->chn_ready |= (1 << cc);
2081 if ((dev->chn_ready & 0x0f) != 0x0f)
2082 break;
2083 /* all channels ready */
2084 printk(KERN_INFO "s2255: fw loaded\n");
2085 atomic_set(&dev->fw_data->fw_state,
2086 S2255_FW_SUCCESS);
2087 wake_up(&dev->fw_data->wait_fw);
2088 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002089 case S2255_RESPONSE_STATUS:
Dean Andersonfe85ce92010-06-01 19:12:07 -03002090 channel->vidstatus = pdword[3];
2091 channel->vidstatus_ready = 1;
2092 wake_up(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002093 dprintk(5, "got vidstatus %x chan %d\n",
2094 pdword[3], cc);
2095 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002096 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02002097 printk(KERN_INFO "s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002098 }
2099 default:
2100 pdata++;
2101 break;
2102 }
2103 if (bframe)
2104 break;
2105 } /* for */
2106 if (!bframe)
2107 return -EINVAL;
2108 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002109 channel = &dev->channel[dev->cc];
2110 idx = channel->cur_frame;
2111 frm = &channel->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002112 /* search done. now find out if should be acquiring on this channel */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002113 if (!channel->b_acquire) {
Dean Anderson14d96262008-08-25 13:58:55 -03002114 /* we found a frame, but this channel is turned off */
2115 frm->ulState = S2255_READ_IDLE;
2116 return -EINVAL;
2117 }
2118
2119 if (frm->ulState == S2255_READ_IDLE) {
2120 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002121 frm->cur_size = 0;
2122 }
2123
Dean Anderson14d96262008-08-25 13:58:55 -03002124 /* skip the marker 512 bytes (and offset if out of sync) */
2125 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2126
Dean Anderson38f993a2008-06-26 23:15:51 -03002127
2128 if (frm->lpvbits == NULL) {
2129 dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
2130 frm, dev, dev->cc, idx);
2131 return -ENOMEM;
2132 }
2133
2134 pdest = frm->lpvbits + frm->cur_size;
2135
Dean Anderson14d96262008-08-25 13:58:55 -03002136 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002137
Dean Andersonfe85ce92010-06-01 19:12:07 -03002138 size = channel->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002139
Dean Anderson14d96262008-08-25 13:58:55 -03002140 /* sanity check on pdest */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002141 if ((copy_size + frm->cur_size) < channel->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03002142 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002143
Dean Anderson38f993a2008-06-26 23:15:51 -03002144 frm->cur_size += copy_size;
Dean Anderson14d96262008-08-25 13:58:55 -03002145 dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002146
Dean Anderson14d96262008-08-25 13:58:55 -03002147 if (frm->cur_size >= size) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002148 dprintk(2, "****************[%d]Buffer[%d]full*************\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002149 dev->cc, idx);
2150 channel->last_frame = channel->cur_frame;
2151 channel->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002152 /* end of system frame ring buffer, start at zero */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002153 if ((channel->cur_frame == SYS_FRAMES) ||
2154 (channel->cur_frame == channel->buffer.dwFrames))
2155 channel->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002156 /* frame ready */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002157 if (channel->b_acquire)
2158 s2255_got_frame(channel, channel->jpg_size);
2159 channel->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03002160 frm->ulState = S2255_READ_IDLE;
2161 frm->cur_size = 0;
2162
Dean Anderson38f993a2008-06-26 23:15:51 -03002163 }
2164 /* done successfully */
2165 return 0;
2166}
2167
2168static void s2255_read_video_callback(struct s2255_dev *dev,
2169 struct s2255_pipeinfo *pipe_info)
2170{
2171 int res;
2172 dprintk(50, "callback read video \n");
2173
2174 if (dev->cc >= MAX_CHANNELS) {
2175 dev->cc = 0;
2176 dev_err(&dev->udev->dev, "invalid channel\n");
2177 return;
2178 }
2179 /* otherwise copy to the system buffers */
2180 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002181 if (res != 0)
2182 dprintk(4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002183
2184 dprintk(50, "callback read video done\n");
2185 return;
2186}
2187
2188static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2189 u16 Index, u16 Value, void *TransferBuffer,
2190 s32 TransferBufferLength, int bOut)
2191{
2192 int r;
2193 if (!bOut) {
2194 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2195 Request,
2196 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2197 USB_DIR_IN,
2198 Value, Index, TransferBuffer,
2199 TransferBufferLength, HZ * 5);
2200 } else {
2201 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2202 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2203 Value, Index, TransferBuffer,
2204 TransferBufferLength, HZ * 5);
2205 }
2206 return r;
2207}
2208
2209/*
2210 * retrieve FX2 firmware version. future use.
2211 * @param dev pointer to device extension
2212 * @return -1 for fail, else returns firmware version as an int(16 bits)
2213 */
2214static int s2255_get_fx2fw(struct s2255_dev *dev)
2215{
2216 int fw;
2217 int ret;
2218 unsigned char transBuffer[64];
2219 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2220 S2255_VR_IN);
2221 if (ret < 0)
2222 dprintk(2, "get fw error: %x\n", ret);
2223 fw = transBuffer[0] + (transBuffer[1] << 8);
2224 dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
2225 return fw;
2226}
2227
2228/*
2229 * Create the system ring buffer to copy frames into from the
2230 * usb read pipe.
2231 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002232static int s2255_create_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002233{
2234 unsigned long i;
2235 unsigned long reqsize;
2236 dprintk(1, "create sys buffers\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002237 channel->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03002238 /* always allocate maximum size(PAL) for system buffers */
2239 reqsize = SYS_FRAMES_MAXSIZE;
2240
2241 if (reqsize > SYS_FRAMES_MAXSIZE)
2242 reqsize = SYS_FRAMES_MAXSIZE;
2243
2244 for (i = 0; i < SYS_FRAMES; i++) {
2245 /* allocate the frames */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002246 channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
2247 dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
2248 &channel->buffer.frame[i], channel->idx, i,
2249 channel->buffer.frame[i].lpvbits);
2250 channel->buffer.frame[i].size = reqsize;
2251 if (channel->buffer.frame[i].lpvbits == NULL) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002252 printk(KERN_INFO "out of memory. using less frames\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002253 channel->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002254 break;
2255 }
2256 }
2257
2258 /* make sure internal states are set */
2259 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002260 channel->buffer.frame[i].ulState = 0;
2261 channel->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002262 }
2263
Dean Andersonfe85ce92010-06-01 19:12:07 -03002264 channel->cur_frame = 0;
2265 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002266 return 0;
2267}
2268
Dean Andersonfe85ce92010-06-01 19:12:07 -03002269static int s2255_release_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002270{
2271 unsigned long i;
2272 dprintk(1, "release sys buffers\n");
2273 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002274 if (channel->buffer.frame[i].lpvbits) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002275 dprintk(1, "vfree %p\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002276 channel->buffer.frame[i].lpvbits);
2277 vfree(channel->buffer.frame[i].lpvbits);
Dean Anderson38f993a2008-06-26 23:15:51 -03002278 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002279 channel->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002280 }
2281 return 0;
2282}
2283
2284static int s2255_board_init(struct s2255_dev *dev)
2285{
Dean Anderson38f993a2008-06-26 23:15:51 -03002286 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2287 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002288 int j;
2289 struct s2255_pipeinfo *pipe = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002290 dprintk(4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002291 memset(pipe, 0, sizeof(*pipe));
2292 pipe->dev = dev;
2293 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2294 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002295
Dean Andersonab85c6a2010-04-08 23:39:12 -03002296 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2297 GFP_KERNEL);
2298 if (pipe->transfer_buffer == NULL) {
2299 dprintk(1, "out of memory!\n");
2300 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002301 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002302 /* query the firmware */
2303 fw_ver = s2255_get_fx2fw(dev);
2304
Dean Andersonabce21f2009-04-23 16:04:41 -03002305 printk(KERN_INFO "2255 usb firmware version %d.%d\n",
2306 (fw_ver >> 8) & 0xff,
2307 fw_ver & 0xff);
2308
2309 if (fw_ver < S2255_CUR_USB_FWVER)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002310 dev_err(&dev->udev->dev,
Dean Andersonabce21f2009-04-23 16:04:41 -03002311 "usb firmware not up to date %d.%d\n",
2312 (fw_ver >> 8) & 0xff,
2313 fw_ver & 0xff);
Dean Anderson38f993a2008-06-26 23:15:51 -03002314
2315 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002316 struct s2255_channel *channel = &dev->channel[j];
2317 channel->b_acquire = 0;
2318 channel->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002319 if (dev->pid == 0x2257 && j > 1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002320 channel->mode.color |= (1 << 16);
2321 channel->jc.quality = S2255_DEF_JPEG_QUAL;
2322 channel->width = LINE_SZ_4CIFS_NTSC;
2323 channel->height = NUM_LINES_4CIFS_NTSC * 2;
2324 channel->fmt = &formats[0];
2325 channel->mode.restart = 1;
2326 channel->req_image_size = get_transfer_size(&mode_def);
2327 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002328 /* create the system buffers */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002329 s2255_create_sys_buffers(channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03002330 }
2331 /* start read pipe */
2332 s2255_start_readpipe(dev);
Dean Anderson85b85482010-04-08 23:51:17 -03002333 dprintk(1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002334 return 0;
2335}
2336
2337static int s2255_board_shutdown(struct s2255_dev *dev)
2338{
2339 u32 i;
Dean Anderson85b85482010-04-08 23:51:17 -03002340 dprintk(1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002341
2342 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002343 if (dev->channel[i].b_acquire)
2344 s2255_stop_acquire(&dev->channel[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002345 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002346 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002347 for (i = 0; i < MAX_CHANNELS; i++)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002348 s2255_release_sys_buffers(&dev->channel[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002349 /* release transfer buffer */
2350 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002351 return 0;
2352}
2353
2354static void read_pipe_completion(struct urb *purb)
2355{
2356 struct s2255_pipeinfo *pipe_info;
2357 struct s2255_dev *dev;
2358 int status;
2359 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002360 pipe_info = purb->context;
Dean Anderson85b85482010-04-08 23:51:17 -03002361 dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
Dean Anderson38f993a2008-06-26 23:15:51 -03002362 purb->status);
2363 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002364 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002365 return;
2366 }
2367
2368 dev = pipe_info->dev;
2369 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002370 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002371 return;
2372 }
2373 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002374 /* if shutting down, do not resubmit, exit immediately */
2375 if (status == -ESHUTDOWN) {
Dean Anderson85b85482010-04-08 23:51:17 -03002376 dprintk(2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002377 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002378 return;
2379 }
2380
2381 if (pipe_info->state == 0) {
Dean Anderson85b85482010-04-08 23:51:17 -03002382 dprintk(2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002383 return;
2384 }
2385
Dean Andersonb02064c2009-04-30 12:29:38 -03002386 if (status == 0)
2387 s2255_read_video_callback(dev, pipe_info);
2388 else {
2389 pipe_info->err_count++;
Dean Anderson85b85482010-04-08 23:51:17 -03002390 dprintk(1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002391 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002392
Dean Anderson38f993a2008-06-26 23:15:51 -03002393 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2394 /* reuse urb */
2395 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2396 pipe,
2397 pipe_info->transfer_buffer,
2398 pipe_info->cur_transfer_size,
2399 read_pipe_completion, pipe_info);
2400
2401 if (pipe_info->state != 0) {
Pete Eberleina1b4c862011-04-01 21:21:26 -03002402 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
Dean Anderson38f993a2008-06-26 23:15:51 -03002403 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002404 }
2405 } else {
Dean Anderson85b85482010-04-08 23:51:17 -03002406 dprintk(2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002407 }
2408 return;
2409}
2410
2411static int s2255_start_readpipe(struct s2255_dev *dev)
2412{
2413 int pipe;
2414 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002415 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002416 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
Dean Anderson85b85482010-04-08 23:51:17 -03002417 dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002418 pipe_info->state = 1;
2419 pipe_info->err_count = 0;
2420 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2421 if (!pipe_info->stream_urb) {
2422 dev_err(&dev->udev->dev,
2423 "ReadStream: Unable to alloc URB\n");
2424 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002425 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002426 /* transfer buffer allocated in board_init */
2427 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2428 pipe,
2429 pipe_info->transfer_buffer,
2430 pipe_info->cur_transfer_size,
2431 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002432 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2433 if (retval) {
2434 printk(KERN_ERR "s2255: start read pipe failed\n");
2435 return retval;
2436 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002437 return 0;
2438}
2439
2440/* starts acquisition process */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002441static int s2255_start_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002442{
2443 unsigned char *buffer;
2444 int res;
2445 unsigned long chn_rev;
2446 int j;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002447 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2448 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002449 buffer = kzalloc(512, GFP_KERNEL);
2450 if (buffer == NULL) {
2451 dev_err(&dev->udev->dev, "out of mem\n");
2452 return -ENOMEM;
2453 }
2454
Dean Andersonfe85ce92010-06-01 19:12:07 -03002455 channel->last_frame = -1;
2456 channel->bad_payload = 0;
2457 channel->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002458 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002459 channel->buffer.frame[j].ulState = 0;
2460 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002461 }
2462
2463 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002464 *(__le32 *) buffer = IN_DATA_TOKEN;
2465 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2466 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002467 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2468 if (res != 0)
2469 dev_err(&dev->udev->dev, "CMD_START error\n");
2470
Dean Andersonfe85ce92010-06-01 19:12:07 -03002471 dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03002472 kfree(buffer);
2473 return 0;
2474}
2475
Dean Andersonfe85ce92010-06-01 19:12:07 -03002476static int s2255_stop_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002477{
2478 unsigned char *buffer;
2479 int res;
2480 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002481 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2482 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002483 buffer = kzalloc(512, GFP_KERNEL);
2484 if (buffer == NULL) {
2485 dev_err(&dev->udev->dev, "out of mem\n");
2486 return -ENOMEM;
2487 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002488 /* send the stop command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002489 *(__le32 *) buffer = IN_DATA_TOKEN;
2490 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2491 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002492 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002493 if (res != 0)
2494 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002495 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002496 channel->b_acquire = 0;
2497 dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
Dean Anderson14d96262008-08-25 13:58:55 -03002498 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002499}
2500
2501static void s2255_stop_readpipe(struct s2255_dev *dev)
2502{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002503 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002504
Dean Andersonab85c6a2010-04-08 23:39:12 -03002505 pipe->state = 0;
2506 if (pipe->stream_urb) {
2507 /* cancel urb */
2508 usb_kill_urb(pipe->stream_urb);
2509 usb_free_urb(pipe->stream_urb);
2510 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002511 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002512 dprintk(4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002513 return;
2514}
2515
Dean Anderson14d96262008-08-25 13:58:55 -03002516static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002517{
Dean Anderson14d96262008-08-25 13:58:55 -03002518 if (reset)
2519 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002520 dev->fw_data->fw_size = dev->fw_data->fw->size;
2521 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2522 memcpy(dev->fw_data->pfw_data,
2523 dev->fw_data->fw->data, CHUNK_SIZE);
2524 dev->fw_data->fw_loaded = CHUNK_SIZE;
2525 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2526 usb_sndbulkpipe(dev->udev, 2),
2527 dev->fw_data->pfw_data,
2528 CHUNK_SIZE, s2255_fwchunk_complete,
2529 dev->fw_data);
2530 mod_timer(&dev->timer, jiffies + HZ);
2531}
2532
2533/* standard usb probe function */
2534static int s2255_probe(struct usb_interface *interface,
2535 const struct usb_device_id *id)
2536{
2537 struct s2255_dev *dev = NULL;
2538 struct usb_host_interface *iface_desc;
2539 struct usb_endpoint_descriptor *endpoint;
2540 int i;
2541 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002542 __le32 *pdata;
2543 int fw_size;
Dean Anderson85b85482010-04-08 23:51:17 -03002544 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002545 /* allocate memory for our device state and initialize it to zero */
2546 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2547 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002548 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002549 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002550 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002551 atomic_set(&dev->num_channels, 0);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002552 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002553 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2554 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002555 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002556 mutex_init(&dev->lock);
2557 mutex_init(&dev->open_lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002558 /* grab usb_device and save it */
2559 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2560 if (dev->udev == NULL) {
2561 dev_err(&interface->dev, "null usb device\n");
2562 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002563 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002564 }
Dean Andersond62e85a2010-04-09 19:54:26 -03002565 dprintk(1, "dev: %p, udev %p interface %p\n", dev,
Dean Anderson38f993a2008-06-26 23:15:51 -03002566 dev->udev, interface);
2567 dev->interface = interface;
2568 /* set up the endpoint information */
2569 iface_desc = interface->cur_altsetting;
2570 dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
2571 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2572 endpoint = &iface_desc->endpoint[i].desc;
2573 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2574 /* we found the bulk in endpoint */
2575 dev->read_endpoint = endpoint->bEndpointAddress;
2576 }
2577 }
2578
2579 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002580 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002581 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002582 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002583 init_timer(&dev->timer);
2584 dev->timer.function = s2255_timer;
2585 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002586 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002587 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002588 struct s2255_channel *channel = &dev->channel[i];
2589 dev->channel[i].idx = i;
2590 init_waitqueue_head(&channel->wait_setmode);
2591 init_waitqueue_head(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002592 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002593
2594 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002595 if (!dev->fw_data->fw_urb) {
2596 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002597 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002598 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002599
Dean Anderson38f993a2008-06-26 23:15:51 -03002600 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2601 if (!dev->fw_data->pfw_data) {
2602 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002603 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002604 }
2605 /* load the first chunk */
2606 if (request_firmware(&dev->fw_data->fw,
2607 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2608 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002609 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002610 }
Dean Anderson14d96262008-08-25 13:58:55 -03002611 /* check the firmware is valid */
2612 fw_size = dev->fw_data->fw->size;
2613 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002614
Dean Anderson14d96262008-08-25 13:58:55 -03002615 if (*pdata != S2255_FW_MARKER) {
2616 printk(KERN_INFO "Firmware invalid.\n");
2617 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002618 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002619 } else {
2620 /* make sure firmware is the latest */
2621 __le32 *pRel;
2622 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2623 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
Dean Anderson4de39f52010-03-03 19:39:19 -03002624 dev->dsp_fw_ver = *pRel;
2625 if (*pRel < S2255_CUR_DSP_FWVER)
2626 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002627 if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002628 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
Dean Andersonfe85ce92010-06-01 19:12:07 -03002629 " or above.\n", S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002630 }
Dean Anderson14d96262008-08-25 13:58:55 -03002631 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002632 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002633 retval = s2255_board_init(dev);
2634 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002635 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002636 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002637 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002638 /* loads v4l specific */
2639 retval = s2255_probe_v4l(dev);
2640 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002641 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002642 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2643 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002644errorBOARDINIT:
2645 s2255_board_shutdown(dev);
2646errorFWMARKER:
2647 release_firmware(dev->fw_data->fw);
2648errorREQFW:
2649 kfree(dev->fw_data->pfw_data);
2650errorFWDATA2:
2651 usb_free_urb(dev->fw_data->fw_urb);
2652errorFWURB:
2653 del_timer(&dev->timer);
2654errorEP:
2655 usb_put_dev(dev->udev);
2656errorUDEV:
2657 kfree(dev->fw_data);
2658 mutex_destroy(&dev->open_lock);
2659 mutex_destroy(&dev->lock);
2660errorFWDATA1:
2661 kfree(dev);
2662 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002663 return retval;
2664}
2665
2666/* disconnect routine. when board is removed physically or with rmmod */
2667static void s2255_disconnect(struct usb_interface *interface)
2668{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002669 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002670 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002671 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002672 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002673 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002674 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002675 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002676 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002677 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002678 for (i = 0; i < channels; i++)
2679 video_unregister_device(&dev->channel[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002680 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002681 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2682 wake_up(&dev->fw_data->wait_fw);
2683 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002684 dev->channel[i].setmode_ready = 1;
2685 wake_up(&dev->channel[i].wait_setmode);
2686 dev->channel[i].vidstatus_ready = 1;
2687 wake_up(&dev->channel[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002688 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002689 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002690 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002691 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002692}
2693
2694static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002695 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002696 .probe = s2255_probe,
2697 .disconnect = s2255_disconnect,
2698 .id_table = s2255_table,
2699};
2700
2701static int __init usb_s2255_init(void)
2702{
2703 int result;
Dean Anderson38f993a2008-06-26 23:15:51 -03002704 /* register this driver with the USB subsystem */
2705 result = usb_register(&s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002706 if (result)
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002707 pr_err(KBUILD_MODNAME
Dean Andersonff7e22d2010-04-08 23:38:07 -03002708 ": usb_register failed. Error number %d\n", result);
2709 dprintk(2, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002710 return result;
2711}
2712
2713static void __exit usb_s2255_exit(void)
2714{
2715 usb_deregister(&s2255_driver);
2716}
2717
2718module_init(usb_s2255_init);
2719module_exit(usb_s2255_exit);
2720
2721MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2722MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2723MODULE_LICENSE("GPL");