blob: 517901b25bf8414fce8f2b1b82abc1481a6d620c [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 Andersond86c6a82014-02-04 17:18:03 -03004 * Copyright (C) 2007-2014 by Sensoray Company Inc.
Dean Anderson38f993a2008-06-26 23:15:51 -03005 * Dean Anderson
6 *
7 * Some video buffer code based on vivi driver:
8 *
9 * Sensoray 2255 device supports 4 simultaneous channels.
10 * The channels are not "crossbar" inputs, they are physically
11 * attached to separate video decoders.
12 *
13 * Because of USB2.0 bandwidth limitations. There is only a
14 * certain amount of data which may be transferred at one time.
15 *
16 * Example maximum bandwidth utilization:
17 *
18 * -full size, color mode YUYV or YUV422P: 2 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030019 * -full or half size Grey scale: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030020 * -half size, color mode YUYV or YUV422P: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030021 * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
22 * at once.
Dean Anderson38f993a2008-06-26 23:15:51 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * (at your option) any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 */
38
39#include <linux/module.h>
40#include <linux/firmware.h>
41#include <linux/kernel.h>
42#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090043#include <linux/slab.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030044#include <linux/videodev2.h>
Hans Verkuilfeb75f02008-07-27 06:30:21 -030045#include <linux/mm.h>
Hans Verkuil44d06d82013-02-15 05:59:00 -030046#include <linux/vmalloc.h>
47#include <linux/usb.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030048#include <media/videobuf-vmalloc.h>
49#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030050#include <media/v4l2-device.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030051#include <media/v4l2-ioctl.h>
Hans Verkuil192f1e72013-02-15 05:51:21 -030052#include <media/v4l2-ctrls.h>
Hans Verkuil44d06d82013-02-15 05:59:00 -030053#include <media/v4l2-event.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030054
Dean Andersond86c6a82014-02-04 17:18:03 -030055#define S2255_VERSION "1.24.1"
Dean Anderson38f993a2008-06-26 23:15:51 -030056#define FIRMWARE_FILE_NAME "f2255usb.bin"
57
Dean Anderson22b88d42008-08-29 15:33:19 -030058/* default JPEG quality */
59#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030060/* vendor request in */
61#define S2255_VR_IN 0
62/* vendor request out */
63#define S2255_VR_OUT 1
64/* firmware query */
65#define S2255_VR_FW 0x30
66/* USB endpoint number for configuring the device */
67#define S2255_CONFIG_EP 2
68/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030069#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030070/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030071#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson9da62eb2014-02-05 14:58:06 -030072#define S2255_MIN_BUFS 2
Dean Anderson14d96262008-08-25 13:58:55 -030073#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030074#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030075#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
76#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
77#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
78#define S2255_RESPONSE_FW cpu_to_le32(0x10)
79#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030080#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030081#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030082#define SYS_FRAMES 4
83/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030084#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
85#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030086#define LINE_SZ_4CIFS_NTSC 640
87#define LINE_SZ_2CIFS_NTSC 640
88#define LINE_SZ_1CIFS_NTSC 320
89#define LINE_SZ_4CIFS_PAL 704
90#define LINE_SZ_2CIFS_PAL 704
91#define LINE_SZ_1CIFS_PAL 352
92#define NUM_LINES_4CIFS_NTSC 240
93#define NUM_LINES_2CIFS_NTSC 240
94#define NUM_LINES_1CIFS_NTSC 240
95#define NUM_LINES_4CIFS_PAL 288
96#define NUM_LINES_2CIFS_PAL 288
97#define NUM_LINES_1CIFS_PAL 288
98#define LINE_SZ_DEF 640
99#define NUM_LINES_DEF 240
100
101
102/* predefined settings */
103#define FORMAT_NTSC 1
104#define FORMAT_PAL 2
105
106#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
107#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
108#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300109/* SCALE_4CIFSI is the 2 fields interpolated into one */
110#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300111
112#define COLOR_YUVPL 1 /* YUV planar */
113#define COLOR_YUVPK 2 /* YUV packed */
114#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300115#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300116
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300117#define MASK_COLOR 0x000000ff
118#define MASK_JPG_QUALITY 0x0000ff00
119#define MASK_INPUT_TYPE 0x000f0000
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300120/* frame decimation. */
Dean Anderson38f993a2008-06-26 23:15:51 -0300121#define FDEC_1 1 /* capture every frame. default */
122#define FDEC_2 2 /* capture every 2nd frame */
123#define FDEC_3 3 /* capture every 3rd frame */
124#define FDEC_5 5 /* capture every 5th frame */
125
126/*-------------------------------------------------------
127 * Default mode parameters.
128 *-------------------------------------------------------*/
129#define DEF_SCALE SCALE_4CIFS
130#define DEF_COLOR COLOR_YUVPL
131#define DEF_FDEC FDEC_1
132#define DEF_BRIGHT 0
133#define DEF_CONTRAST 0x5c
134#define DEF_SATURATION 0x80
135#define DEF_HUE 0
136
137/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300138#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
Dan Carpenter3b2a6302012-02-17 02:44:10 -0300139#define CMD_2255 0xc2255000
Dean Anderson3fa00602010-03-04 20:47:33 -0300140#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
141#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
142#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
143#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300144
145struct s2255_mode {
146 u32 format; /* input video format (NTSC, PAL) */
147 u32 scale; /* output video scale */
148 u32 color; /* output video color format */
149 u32 fdec; /* frame decimation */
150 u32 bright; /* brightness */
151 u32 contrast; /* contrast */
152 u32 saturation; /* saturation */
153 u32 hue; /* hue (NTSC only)*/
154 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
155 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
156 u32 restart; /* if DSP requires restart */
157};
158
Dean Anderson14d96262008-08-25 13:58:55 -0300159
160#define S2255_READ_IDLE 0
161#define S2255_READ_FRAME 1
162
Dean Anderson38f993a2008-06-26 23:15:51 -0300163/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300164struct s2255_framei {
165 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300166 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300167 void *lpvbits; /* image data */
168 unsigned long cur_size; /* current data copied to it */
169};
170
171/* image buffer structure */
172struct s2255_bufferi {
173 unsigned long dwFrames; /* number of frames in buffer */
174 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
175};
176
177#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
178 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300179 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300180
Dean Anderson38f993a2008-06-26 23:15:51 -0300181/* for firmware loading, fw_state */
182#define S2255_FW_NOTLOADED 0
183#define S2255_FW_LOADED_DSPWAIT 1
184#define S2255_FW_SUCCESS 2
185#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300186#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300187#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300188/* 2255 read states */
189#define S2255_READ_IDLE 0
190#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300191struct s2255_fw {
192 int fw_loaded;
193 int fw_size;
194 struct urb *fw_urb;
195 atomic_t fw_state;
196 void *pfw_data;
197 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300198 const struct firmware *fw;
199};
200
201struct s2255_pipeinfo {
202 u32 max_transfer_size;
203 u32 cur_transfer_size;
204 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300205 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300206 void *stream_urb;
207 void *dev; /* back pointer to s2255_dev struct*/
208 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300209 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300210};
211
212struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300213struct s2255_dev;
214
Dean Anderson5e950fa2014-02-04 18:16:24 -0300215/* 2255 video channel */
216struct s2255_vc {
sensoray-devf5402002014-01-29 15:24:07 -0300217 struct s2255_dev *dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300218 struct video_device vdev;
Hans Verkuil192f1e72013-02-15 05:51:21 -0300219 struct v4l2_ctrl_handler hdl;
Hans Verkuil7041dec2013-02-15 05:53:45 -0300220 struct v4l2_ctrl *jpegqual_ctrl;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300221 int resources;
Dean Andersond86c6a82014-02-04 17:18:03 -0300222 struct list_head buf_list;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300223 struct s2255_bufferi buffer;
224 struct s2255_mode mode;
Hans Verkuil469af772013-02-15 06:12:58 -0300225 v4l2_std_id std;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300226 /* jpeg compression */
Hans Verkuil7041dec2013-02-15 05:53:45 -0300227 unsigned jpegqual;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300228 /* capture parameters (for high quality mode full size) */
229 struct v4l2_captureparm cap_parm;
230 int cur_frame;
231 int last_frame;
232
233 int b_acquire;
234 /* allocated image size */
235 unsigned long req_image_size;
236 /* received packet size */
237 unsigned long pkt_size;
238 int bad_payload;
239 unsigned long frame_count;
240 /* if JPEG image */
241 int jpg_size;
242 /* if channel configured to default state */
243 int configured;
244 wait_queue_head_t wait_setmode;
245 int setmode_ready;
246 /* video status items */
247 int vidstatus;
248 wait_queue_head_t wait_vidstatus;
249 int vidstatus_ready;
250 unsigned int width;
251 unsigned int height;
252 const struct s2255_fmt *fmt;
253 int idx; /* channel number on device, 0-3 */
254};
255
Dean Anderson38f993a2008-06-26 23:15:51 -0300256
257struct s2255_dev {
Dean Anderson5e950fa2014-02-04 18:16:24 -0300258 struct s2255_vc vc[MAX_CHANNELS];
sensoray-devf5402002014-01-29 15:24:07 -0300259 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300260 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300261 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300262 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson38f993a2008-06-26 23:15:51 -0300263 struct usb_device *udev;
264 struct usb_interface *interface;
265 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300266 struct timer_list timer;
267 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300268 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300269 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300270 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300271 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300272 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300273 /* dsp firmware version (f2255usb.bin) */
274 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300275 u16 pid; /* product id */
Dean Anderson38f993a2008-06-26 23:15:51 -0300276};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300277
Dean Anderson65c6edb2010-04-20 17:21:32 -0300278static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
279{
280 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
281}
Dean Anderson38f993a2008-06-26 23:15:51 -0300282
283struct s2255_fmt {
284 char *name;
285 u32 fourcc;
286 int depth;
287};
288
289/* buffer for one video frame */
290struct s2255_buffer {
291 /* common v4l buffer stuff -- must be first */
292 struct videobuf_buffer vb;
Dean Anderson38f993a2008-06-26 23:15:51 -0300293};
294
295struct s2255_fh {
Hans Verkuil44d06d82013-02-15 05:59:00 -0300296 /* this must be the first field in this struct */
297 struct v4l2_fh fh;
Dean Anderson38f993a2008-06-26 23:15:51 -0300298 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300299 struct videobuf_queue vb_vidq;
300 enum v4l2_buf_type type;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300301 struct s2255_vc *vc;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300302 int resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300303};
304
Dean Andersonabce21f2009-04-23 16:04:41 -0300305/* current cypress EEPROM firmware version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300306#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
Dean Anderson4de39f52010-03-03 19:39:19 -0300307/* current DSP FW version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300308#define S2255_CUR_DSP_FWVER 10104
Dean Anderson4de39f52010-03-03 19:39:19 -0300309/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300310#define S2255_MIN_DSP_STATUS 5
311#define S2255_MIN_DSP_COLORFILTER 8
Hans Verkuil469af772013-02-15 06:12:58 -0300312#define S2255_NORMS (V4L2_STD_ALL)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300313
314/* private V4L2 controls */
315
316/*
317 * The following chart displays how COLORFILTER should be set
318 * =========================================================
319 * = fourcc = COLORFILTER =
320 * = ===============================
321 * = = 0 = 1 =
322 * =========================================================
323 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
324 * = = s-video or = composite =
325 * = = B/W camera = input =
326 * =========================================================
327 * = other = color, svideo = color, =
328 * = = = composite =
329 * =========================================================
330 *
331 * Notes:
332 * channels 0-3 on 2255 are composite
333 * channels 0-1 on 2257 are composite, 2-3 are s-video
334 * If COLORFILTER is 0 with a composite color camera connected,
335 * the output will appear monochrome but hatching
336 * will occur.
337 * COLORFILTER is different from "color killer" and "color effects"
338 * for reasons above.
339 */
340#define S2255_V4L2_YC_ON 1
341#define S2255_V4L2_YC_OFF 0
Hans Verkuil192f1e72013-02-15 05:51:21 -0300342#define V4L2_CID_S2255_COLORFILTER (V4L2_CID_USER_S2255_BASE + 0)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300343
Dean Anderson38f993a2008-06-26 23:15:51 -0300344/* frame prefix size (sent once every frame) */
345#define PREFIX_SIZE 512
346
347/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300348static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300349
Dean Anderson38f993a2008-06-26 23:15:51 -0300350static int debug;
Dean Anderson38f993a2008-06-26 23:15:51 -0300351
352static int s2255_start_readpipe(struct s2255_dev *dev);
353static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300354static int s2255_start_acquire(struct s2255_vc *vc);
355static int s2255_stop_acquire(struct s2255_vc *vc);
356static void s2255_fillbuff(struct s2255_vc *vc, struct s2255_buffer *buf,
Dean Andersonfe85ce92010-06-01 19:12:07 -0300357 int jpgsize);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300358static int s2255_set_mode(struct s2255_vc *vc, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300359static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300360static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300361static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300362static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
363 u16 index, u16 value, void *buf,
364 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300365
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300366/* dev_err macro with driver name */
367#define S2255_DRIVER_NAME "s2255"
368#define s2255_dev_err(dev, fmt, arg...) \
369 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
370
sensoray-devf5402002014-01-29 15:24:07 -0300371#define dprintk(dev, level, fmt, arg...) \
372 v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
Dean Anderson38f993a2008-06-26 23:15:51 -0300373
Dean Anderson38f993a2008-06-26 23:15:51 -0300374static struct usb_driver s2255_driver;
375
Dean Anderson38f993a2008-06-26 23:15:51 -0300376/* start video number */
377static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
378
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300379/* Enable jpeg capture. */
380static int jpeg_enable = 1;
381
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300382module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300383MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300384module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300385MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300386module_param(jpeg_enable, int, 0644);
387MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
Dean Anderson38f993a2008-06-26 23:15:51 -0300388
389/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300390#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300391static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300392 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
393 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300394 { } /* Terminating entry */
395};
396MODULE_DEVICE_TABLE(usb, s2255_table);
397
Dean Anderson38f993a2008-06-26 23:15:51 -0300398#define BUFFER_TIMEOUT msecs_to_jiffies(400)
399
Dean Anderson38f993a2008-06-26 23:15:51 -0300400/* image formats. */
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300401/* JPEG formats must be defined last to support jpeg_enable parameter */
Dean Anderson38f993a2008-06-26 23:15:51 -0300402static const struct s2255_fmt formats[] = {
403 {
Dean Anderson38f993a2008-06-26 23:15:51 -0300404 .name = "4:2:2, packed, YUYV",
405 .fourcc = V4L2_PIX_FMT_YUYV,
406 .depth = 16
407
408 }, {
409 .name = "4:2:2, packed, UYVY",
410 .fourcc = V4L2_PIX_FMT_UYVY,
411 .depth = 16
412 }, {
Hans Verkuil5c632b22013-02-26 14:29:04 -0300413 .name = "4:2:2, planar, YUV422P",
414 .fourcc = V4L2_PIX_FMT_YUV422P,
415 .depth = 16
416
417 }, {
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300418 .name = "8bpp GREY",
419 .fourcc = V4L2_PIX_FMT_GREY,
420 .depth = 8
421 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300422 .name = "JPG",
423 .fourcc = V4L2_PIX_FMT_JPEG,
424 .depth = 24
425 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300426 .name = "MJPG",
427 .fourcc = V4L2_PIX_FMT_MJPEG,
428 .depth = 24
Dean Anderson38f993a2008-06-26 23:15:51 -0300429 }
430};
431
Dean Anderson5e950fa2014-02-04 18:16:24 -0300432static int norm_maxw(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300433{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300434 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300435 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
436}
437
Dean Anderson5e950fa2014-02-04 18:16:24 -0300438static int norm_maxh(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300439{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300440 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300441 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
442}
443
Dean Anderson5e950fa2014-02-04 18:16:24 -0300444static int norm_minw(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300445{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300446 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300447 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
448}
449
Dean Anderson5e950fa2014-02-04 18:16:24 -0300450static int norm_minh(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300451{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300452 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300453 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
454}
455
456
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300457/*
458 * TODO: fixme: move YUV reordering to hardware
459 * converts 2255 planar format to yuyv or uyvy
460 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300461static void planar422p_to_yuv_packed(const unsigned char *in,
462 unsigned char *out,
463 int width, int height,
464 int fmt)
465{
466 unsigned char *pY;
467 unsigned char *pCb;
468 unsigned char *pCr;
469 unsigned long size = height * width;
470 unsigned int i;
471 pY = (unsigned char *)in;
472 pCr = (unsigned char *)in + height * width;
473 pCb = (unsigned char *)in + height * width + (height * width / 2);
474 for (i = 0; i < size * 2; i += 4) {
475 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
476 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
477 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
478 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
479 }
480 return;
481}
482
Hans Verkuild45b9b82008-09-04 03:33:43 -0300483static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300484{
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300485 s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
sensoray-devf5402002014-01-29 15:24:07 -0300486 msleep(20);
Dean Anderson14d96262008-08-25 13:58:55 -0300487 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300488 msleep(600);
489 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300490 return;
491}
Dean Anderson38f993a2008-06-26 23:15:51 -0300492
493/* kickstarts the firmware loading. from probe
494 */
495static void s2255_timer(unsigned long user_data)
496{
497 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson38f993a2008-06-26 23:15:51 -0300498 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
sensoray-devf5402002014-01-29 15:24:07 -0300499 pr_err("s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300500 atomic_set(&data->fw_state, S2255_FW_FAILED);
501 /* wake up anything waiting for the firmware */
502 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300503 return;
504 }
505}
506
Dean Anderson38f993a2008-06-26 23:15:51 -0300507
508/* this loads the firmware asynchronously.
Hans Verkuil0b84caa2013-02-26 14:14:19 -0300509 Originally this was done synchronously in probe.
Dean Anderson38f993a2008-06-26 23:15:51 -0300510 But it is better to load it asynchronously here than block
511 inside the probe function. Blocking inside probe affects boot time.
512 FW loading is triggered by the timer in the probe function
513*/
514static void s2255_fwchunk_complete(struct urb *urb)
515{
516 struct s2255_fw *data = urb->context;
517 struct usb_device *udev = urb->dev;
518 int len;
Dean Anderson38f993a2008-06-26 23:15:51 -0300519 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300520 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
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 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300527 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300528 atomic_set(&data->fw_state, S2255_FW_FAILED);
529 /* wake up anything waiting for the firmware */
530 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300531 return;
532 }
533#define CHUNK_SIZE 512
534 /* all USB transfers must be done with continuous kernel memory.
535 can't allocate more than 128k in current linux kernel, so
536 upload the firmware in chunks
537 */
538 if (data->fw_loaded < data->fw_size) {
539 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
540 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
541
542 if (len < CHUNK_SIZE)
543 memset(data->pfw_data, 0, CHUNK_SIZE);
544
Dean Anderson38f993a2008-06-26 23:15:51 -0300545 memcpy(data->pfw_data,
546 (char *) data->fw->data + data->fw_loaded, len);
547
548 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
549 data->pfw_data, CHUNK_SIZE,
550 s2255_fwchunk_complete, data);
551 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
552 dev_err(&udev->dev, "failed submit URB\n");
553 atomic_set(&data->fw_state, S2255_FW_FAILED);
554 /* wake up anything waiting for the firmware */
555 wake_up(&data->wait_fw);
556 return;
557 }
558 data->fw_loaded += len;
sensoray-devf5402002014-01-29 15:24:07 -0300559 } else
Dean Anderson38f993a2008-06-26 23:15:51 -0300560 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson38f993a2008-06-26 23:15:51 -0300561 return;
562
563}
564
Dean Anderson5e950fa2014-02-04 18:16:24 -0300565static int s2255_got_frame(struct s2255_vc *vc, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300566{
Dean Anderson38f993a2008-06-26 23:15:51 -0300567 struct s2255_buffer *buf;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300568 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300569 unsigned long flags = 0;
570 int rc = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300571 spin_lock_irqsave(&dev->slock, flags);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300572 if (list_empty(&vc->buf_list)) {
sensoray-devf5402002014-01-29 15:24:07 -0300573 dprintk(dev, 1, "No active queue to serve\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300574 rc = -1;
575 goto unlock;
576 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300577 buf = list_entry(vc->buf_list.next,
Dean Anderson38f993a2008-06-26 23:15:51 -0300578 struct s2255_buffer, vb.queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300579 list_del(&buf->vb.queue);
Sakari Ailus8e6057b2012-09-15 15:14:42 -0300580 v4l2_get_timestamp(&buf->vb.ts);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300581 s2255_fillbuff(vc, buf, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300582 wake_up(&buf->vb.done);
sensoray-devf5402002014-01-29 15:24:07 -0300583 dprintk(dev, 2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
Dean Anderson38f993a2008-06-26 23:15:51 -0300584unlock:
585 spin_unlock_irqrestore(&dev->slock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300586 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300587}
588
Dean Anderson38f993a2008-06-26 23:15:51 -0300589static const struct s2255_fmt *format_by_fourcc(int fourcc)
590{
591 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300592 for (i = 0; i < ARRAY_SIZE(formats); i++) {
593 if (-1 == formats[i].fourcc)
594 continue;
sensoray-devf5402002014-01-29 15:24:07 -0300595 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
596 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
597 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300598 if (formats[i].fourcc == fourcc)
599 return formats + i;
600 }
601 return NULL;
602}
603
Dean Anderson38f993a2008-06-26 23:15:51 -0300604/* video buffer vmalloc implementation based partly on VIVI driver which is
605 * Copyright (c) 2006 by
606 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
607 * Ted Walther <ted--a.t--enumera.com>
608 * John Sokol <sokol--a.t--videotechnology.com>
609 * http://v4l.videotechnology.com/
610 *
611 */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300612static void s2255_fillbuff(struct s2255_vc *vc,
Dean Andersonfe85ce92010-06-01 19:12:07 -0300613 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300614{
615 int pos = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300616 const char *tmpbuf;
617 char *vbuf = videobuf_to_vmalloc(&buf->vb);
618 unsigned long last_frame;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300619 struct s2255_dev *dev = vc->dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300620
621 if (!vbuf)
622 return;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300623 last_frame = vc->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300624 if (last_frame != -1) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300625 tmpbuf =
Dean Anderson5e950fa2014-02-04 18:16:24 -0300626 (const char *)vc->buffer.frame[last_frame].lpvbits;
Dean Anderson8bf405a2014-02-05 15:18:55 -0300627 switch (vc->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300628 case V4L2_PIX_FMT_YUYV:
629 case V4L2_PIX_FMT_UYVY:
630 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
631 vbuf, buf->vb.width,
632 buf->vb.height,
Dean Anderson8bf405a2014-02-05 15:18:55 -0300633 vc->fmt->fourcc);
Dean Anderson38f993a2008-06-26 23:15:51 -0300634 break;
635 case V4L2_PIX_FMT_GREY:
636 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
637 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300638 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300639 case V4L2_PIX_FMT_MJPEG:
Dean Anderson14d96262008-08-25 13:58:55 -0300640 buf->vb.size = jpgsize;
641 memcpy(vbuf, tmpbuf, buf->vb.size);
642 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300643 case V4L2_PIX_FMT_YUV422P:
644 memcpy(vbuf, tmpbuf,
645 buf->vb.width * buf->vb.height * 2);
646 break;
647 default:
sensoray-devf5402002014-01-29 15:24:07 -0300648 pr_info("s2255: unknown format?\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300649 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300650 vc->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300651 } else {
sensoray-devf5402002014-01-29 15:24:07 -0300652 pr_err("s2255: =======no frame\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300653 return;
Dean Anderson38f993a2008-06-26 23:15:51 -0300654 }
sensoray-devf5402002014-01-29 15:24:07 -0300655 dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n",
Dean Anderson38f993a2008-06-26 23:15:51 -0300656 (unsigned long)vbuf, pos);
657 /* tell v4l buffer was filled */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300658 buf->vb.field_count = vc->frame_count * 2;
Sakari Ailus8e6057b2012-09-15 15:14:42 -0300659 v4l2_get_timestamp(&buf->vb.ts);
Dean Anderson38f993a2008-06-26 23:15:51 -0300660 buf->vb.state = VIDEOBUF_DONE;
661}
662
663
664/* ------------------------------------------------------------------
665 Videobuf operations
666 ------------------------------------------------------------------*/
667
Dean Anderson9da62eb2014-02-05 14:58:06 -0300668static int buffer_setup(struct videobuf_queue *vq, unsigned int *nbuffers,
Dean Anderson38f993a2008-06-26 23:15:51 -0300669 unsigned int *size)
670{
671 struct s2255_fh *fh = vq->priv_data;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300672 struct s2255_vc *vc = fh->vc;
673 *size = vc->width * vc->height * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300674
Dean Anderson9da62eb2014-02-05 14:58:06 -0300675 if (*nbuffers < S2255_MIN_BUFS)
676 *nbuffers = S2255_MIN_BUFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300677
678 return 0;
679}
680
681static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
682{
Dean Anderson38f993a2008-06-26 23:15:51 -0300683 videobuf_vmalloc_free(&buf->vb);
684 buf->vb.state = VIDEOBUF_NEEDS_INIT;
685}
686
687static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
688 enum v4l2_field field)
689{
690 struct s2255_fh *fh = vq->priv_data;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300691 struct s2255_vc *vc = fh->vc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300692 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
693 int rc;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300694 int w = vc->width;
695 int h = vc->height;
sensoray-devf5402002014-01-29 15:24:07 -0300696 dprintk(fh->dev, 4, "%s, field=%d\n", __func__, field);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300697 if (vc->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300698 return -EINVAL;
699
Dean Anderson5e950fa2014-02-04 18:16:24 -0300700 if ((w < norm_minw(vc)) ||
701 (w > norm_maxw(vc)) ||
702 (h < norm_minh(vc)) ||
703 (h > norm_maxh(vc))) {
sensoray-devf5402002014-01-29 15:24:07 -0300704 dprintk(fh->dev, 4, "invalid buffer prepare\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300705 return -EINVAL;
706 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300707 buf->vb.size = w * h * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300708 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
sensoray-devf5402002014-01-29 15:24:07 -0300709 dprintk(fh->dev, 4, "invalid buffer prepare\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300710 return -EINVAL;
711 }
712
Dean Andersonfe85ce92010-06-01 19:12:07 -0300713 buf->vb.width = w;
714 buf->vb.height = h;
Dean Anderson38f993a2008-06-26 23:15:51 -0300715 buf->vb.field = field;
716
Dean Anderson38f993a2008-06-26 23:15:51 -0300717 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
718 rc = videobuf_iolock(vq, &buf->vb, NULL);
719 if (rc < 0)
720 goto fail;
721 }
722
723 buf->vb.state = VIDEOBUF_PREPARED;
724 return 0;
725fail:
726 free_buffer(vq, buf);
727 return rc;
728}
729
730static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
731{
732 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
733 struct s2255_fh *fh = vq->priv_data;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300734 struct s2255_vc *vc = fh->vc;
sensoray-devf5402002014-01-29 15:24:07 -0300735 dprintk(fh->dev, 1, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300736 buf->vb.state = VIDEOBUF_QUEUED;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300737 list_add_tail(&buf->vb.queue, &vc->buf_list);
Dean Anderson38f993a2008-06-26 23:15:51 -0300738}
739
740static void buffer_release(struct videobuf_queue *vq,
741 struct videobuf_buffer *vb)
742{
743 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
744 struct s2255_fh *fh = vq->priv_data;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300745 dprintk(fh->dev, 4, "%s %d\n", __func__, fh->vc->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -0300746 free_buffer(vq, buf);
747}
748
749static struct videobuf_queue_ops s2255_video_qops = {
750 .buf_setup = buffer_setup,
751 .buf_prepare = buffer_prepare,
752 .buf_queue = buffer_queue,
753 .buf_release = buffer_release,
754};
755
756
Dean Andersonfe85ce92010-06-01 19:12:07 -0300757static int res_get(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300758{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300759 struct s2255_vc *vc = fh->vc;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300760 /* is it free? */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300761 if (vc->resources)
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300762 return 0; /* no, someone else uses it */
Dean Anderson38f993a2008-06-26 23:15:51 -0300763 /* it's free, grab it */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300764 vc->resources = 1;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300765 fh->resources = 1;
sensoray-devf5402002014-01-29 15:24:07 -0300766 dprintk(fh->dev, 1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300767 return 1;
768}
769
Dean Andersonfe85ce92010-06-01 19:12:07 -0300770static int res_locked(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300771{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300772 return fh->vc->resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300773}
774
Dean Andersonf78d92c2008-07-22 14:43:27 -0300775static int res_check(struct s2255_fh *fh)
776{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300777 return fh->resources;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300778}
779
780
Dean Andersonfe85ce92010-06-01 19:12:07 -0300781static void res_free(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300782{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300783 struct s2255_vc *vc = fh->vc;
784 vc->resources = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300785 fh->resources = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300786}
787
Dean Anderson38f993a2008-06-26 23:15:51 -0300788static int vidioc_querycap(struct file *file, void *priv,
789 struct v4l2_capability *cap)
790{
791 struct s2255_fh *fh = file->private_data;
792 struct s2255_dev *dev = fh->dev;
Hans Verkuil39696002013-02-07 07:06:21 -0300793
Dean Anderson38f993a2008-06-26 23:15:51 -0300794 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
795 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300796 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Hans Verkuil39696002013-02-07 07:06:21 -0300797 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
798 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300799 return 0;
800}
801
802static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
803 struct v4l2_fmtdesc *f)
804{
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300805 int index = f->index;
Dean Anderson38f993a2008-06-26 23:15:51 -0300806
807 if (index >= ARRAY_SIZE(formats))
808 return -EINVAL;
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300809 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
810 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
811 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300812 strlcpy(f->description, formats[index].name, sizeof(f->description));
813 f->pixelformat = formats[index].fourcc;
814 return 0;
815}
816
817static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
818 struct v4l2_format *f)
819{
820 struct s2255_fh *fh = priv;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300821 struct s2255_vc *vc = fh->vc;
822 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300823
Dean Anderson5e950fa2014-02-04 18:16:24 -0300824 f->fmt.pix.width = vc->width;
825 f->fmt.pix.height = vc->height;
Hans Verkuil92513612013-02-15 06:05:08 -0300826 if (f->fmt.pix.height >=
827 (is_ntsc ? NUM_LINES_1CIFS_NTSC : NUM_LINES_1CIFS_PAL) * 2)
828 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
829 else
830 f->fmt.pix.field = V4L2_FIELD_TOP;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300831 f->fmt.pix.pixelformat = vc->fmt->fourcc;
832 f->fmt.pix.bytesperline = f->fmt.pix.width * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300833 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300834 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
835 f->fmt.pix.priv = 0;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300836 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300837}
838
839static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
840 struct v4l2_format *f)
841{
842 const struct s2255_fmt *fmt;
843 enum v4l2_field field;
Dean Anderson38f993a2008-06-26 23:15:51 -0300844 struct s2255_fh *fh = priv;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300845 struct s2255_vc *vc = fh->vc;
846 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300847
848 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
849
850 if (fmt == NULL)
851 return -EINVAL;
852
853 field = f->fmt.pix.field;
Dean Anderson38f993a2008-06-26 23:15:51 -0300854
sensoray-devf5402002014-01-29 15:24:07 -0300855 dprintk(fh->dev, 50, "%s NTSC: %d suggested width: %d, height: %d\n",
Dean Anderson85b85482010-04-08 23:51:17 -0300856 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300857 if (is_ntsc) {
858 /* NTSC */
859 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
860 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300861 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300862 } else {
863 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
Hans Verkuil92513612013-02-15 06:05:08 -0300864 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300865 }
866 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
867 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
868 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
869 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
870 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
871 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
872 else
873 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
874 } else {
875 /* PAL */
876 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
877 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300878 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300879 } else {
880 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300881 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300882 }
Hans Verkuil92513612013-02-15 06:05:08 -0300883 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300884 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300885 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300886 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300887 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300888 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300889 else
Dean Anderson38f993a2008-06-26 23:15:51 -0300890 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300891 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300892 f->fmt.pix.field = field;
893 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
894 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300895 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
896 f->fmt.pix.priv = 0;
sensoray-devf5402002014-01-29 15:24:07 -0300897 dprintk(fh->dev, 50, "%s: set width %d height %d field %d\n", __func__,
Dean Anderson85b85482010-04-08 23:51:17 -0300898 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300899 return 0;
900}
901
902static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
903 struct v4l2_format *f)
904{
905 struct s2255_fh *fh = priv;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300906 struct s2255_vc *vc = fh->vc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300907 const struct s2255_fmt *fmt;
908 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300909 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300910 int ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300911
912 ret = vidioc_try_fmt_vid_cap(file, fh, f);
913
914 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300915 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300916
917 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
918
919 if (fmt == NULL)
920 return -EINVAL;
921
922 mutex_lock(&q->vb_lock);
923
924 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
sensoray-devf5402002014-01-29 15:24:07 -0300925 dprintk(fh->dev, 1, "queue busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300926 ret = -EBUSY;
927 goto out_s_fmt;
928 }
929
Dean Andersonfe85ce92010-06-01 19:12:07 -0300930 if (res_locked(fh)) {
sensoray-devf5402002014-01-29 15:24:07 -0300931 dprintk(fh->dev, 1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300932 ret = -EBUSY;
933 goto out_s_fmt;
934 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300935 mode = vc->mode;
936 vc->fmt = fmt;
937 vc->width = f->fmt.pix.width;
938 vc->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300939 fh->vb_vidq.field = f->fmt.pix.field;
940 fh->type = f->type;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300941 if (vc->width > norm_minw(vc)) {
942 if (vc->height > norm_minh(vc)) {
943 if (vc->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -0300944 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300945 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -0300946 else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300947 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -0300948 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300949 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300950
951 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300952 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300953 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300954 /* color mode */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300955 switch (vc->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300956 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300957 mode.color &= ~MASK_COLOR;
958 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -0300959 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300960 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300961 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300962 mode.color &= ~MASK_COLOR;
963 mode.color |= COLOR_JPG;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300964 mode.color |= (vc->jpegqual << 8);
Dean Anderson14d96262008-08-25 13:58:55 -0300965 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300966 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300967 mode.color &= ~MASK_COLOR;
968 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300969 break;
970 case V4L2_PIX_FMT_YUYV:
971 case V4L2_PIX_FMT_UYVY:
972 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300973 mode.color &= ~MASK_COLOR;
974 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -0300975 break;
976 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300977 if ((mode.color & MASK_COLOR) != (vc->mode.color & MASK_COLOR))
Dean Andersonfe85ce92010-06-01 19:12:07 -0300978 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300979 else if (mode.scale != vc->mode.scale)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300980 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300981 else if (mode.format != vc->mode.format)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300982 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300983 vc->mode = mode;
984 (void) s2255_set_mode(vc, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300985 ret = 0;
986out_s_fmt:
987 mutex_unlock(&q->vb_lock);
988 return ret;
989}
990
991static int vidioc_reqbufs(struct file *file, void *priv,
992 struct v4l2_requestbuffers *p)
993{
994 int rc;
995 struct s2255_fh *fh = priv;
996 rc = videobuf_reqbufs(&fh->vb_vidq, p);
997 return rc;
998}
999
1000static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1001{
1002 int rc;
1003 struct s2255_fh *fh = priv;
1004 rc = videobuf_querybuf(&fh->vb_vidq, p);
1005 return rc;
1006}
1007
1008static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1009{
1010 int rc;
1011 struct s2255_fh *fh = priv;
1012 rc = videobuf_qbuf(&fh->vb_vidq, p);
1013 return rc;
1014}
1015
1016static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1017{
1018 int rc;
1019 struct s2255_fh *fh = priv;
1020 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1021 return rc;
1022}
1023
Dean Anderson38f993a2008-06-26 23:15:51 -03001024/* write to the configuration pipe, synchronously */
1025static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1026 int size)
1027{
1028 int pipe;
1029 int done;
1030 long retval = -1;
1031 if (udev) {
1032 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1033 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1034 }
1035 return retval;
1036}
1037
1038static u32 get_transfer_size(struct s2255_mode *mode)
1039{
1040 int linesPerFrame = LINE_SZ_DEF;
1041 int pixelsPerLine = NUM_LINES_DEF;
1042 u32 outImageSize;
1043 u32 usbInSize;
1044 unsigned int mask_mult;
1045
1046 if (mode == NULL)
1047 return 0;
1048
1049 if (mode->format == FORMAT_NTSC) {
1050 switch (mode->scale) {
1051 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001052 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001053 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1054 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1055 break;
1056 case SCALE_2CIFS:
1057 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1058 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1059 break;
1060 case SCALE_1CIFS:
1061 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1062 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1063 break;
1064 default:
1065 break;
1066 }
1067 } else if (mode->format == FORMAT_PAL) {
1068 switch (mode->scale) {
1069 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001070 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001071 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1072 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1073 break;
1074 case SCALE_2CIFS:
1075 linesPerFrame = NUM_LINES_2CIFS_PAL;
1076 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1077 break;
1078 case SCALE_1CIFS:
1079 linesPerFrame = NUM_LINES_1CIFS_PAL;
1080 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1081 break;
1082 default:
1083 break;
1084 }
1085 }
1086 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001087 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001088 /* 2 bytes/pixel if not monochrome */
1089 outImageSize *= 2;
1090 }
1091
1092 /* total bytes to send including prefix and 4K padding;
1093 must be a multiple of USB_READ_SIZE */
1094 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1095 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1096 /* if size not a multiple of USB_READ_SIZE */
1097 if (usbInSize & ~mask_mult)
1098 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1099 return usbInSize;
1100}
1101
Dean Anderson85b85482010-04-08 23:51:17 -03001102static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001103{
1104 struct device *dev = &sdev->udev->dev;
1105 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001106 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1107 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001108 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001109 dev_info(dev, "------------------------------------------------\n");
1110}
1111
1112/*
1113 * set mode is the function which controls the DSP.
1114 * the restart parameter in struct s2255_mode should be set whenever
1115 * the image size could change via color format, video system or image
1116 * size.
1117 * When the restart parameter is set, we sleep for ONE frame to allow the
1118 * DSP time to get the new frame
1119 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001120static int s2255_set_mode(struct s2255_vc *vc,
Dean Anderson38f993a2008-06-26 23:15:51 -03001121 struct s2255_mode *mode)
1122{
1123 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001124 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001125 unsigned long chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001126 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001127 int i;
1128
Dean Anderson5e950fa2014-02-04 18:16:24 -03001129 chn_rev = G_chnmap[vc->idx];
1130 dprintk(dev, 3, "%s channel: %d\n", __func__, vc->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001131 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001132 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1133 mode->color &= ~MASK_COLOR;
1134 mode->color |= COLOR_JPG;
1135 mode->color &= ~MASK_JPG_QUALITY;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001136 mode->color |= (vc->jpegqual << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001137 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001138 /* save the mode */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001139 vc->mode = *mode;
1140 vc->req_image_size = get_transfer_size(mode);
1141 dprintk(dev, 1, "%s: reqsize %ld\n", __func__, vc->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001142 buffer = kzalloc(512, GFP_KERNEL);
1143 if (buffer == NULL) {
1144 dev_err(&dev->udev->dev, "out of mem\n");
1145 return -ENOMEM;
1146 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001147 /* set the mode */
1148 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001149 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001150 buffer[2] = CMD_SET_MODE;
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001151 for (i = 0; i < sizeof(struct s2255_mode) / sizeof(u32); i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001152 buffer[3 + i] = cpu_to_le32(((u32 *)&vc->mode)[i]);
1153 vc->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001154 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1155 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001156 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001157 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001158 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001159 if (mode->restart) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001160 wait_event_timeout(vc->wait_setmode,
1161 (vc->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001162 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001163 if (vc->setmode_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001164 dprintk(dev, 0, "s2255: no set mode response\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001165 res = -EFAULT;
1166 }
1167 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001168 /* clear the restart flag */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001169 vc->mode.restart = 0;
1170 dprintk(dev, 1, "%s chn %d, result: %d\n", __func__, vc->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001171 return res;
1172}
1173
Dean Anderson5e950fa2014-02-04 18:16:24 -03001174static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001175{
1176 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001177 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001178 u32 chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001179 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
1180 chn_rev = G_chnmap[vc->idx];
1181 dprintk(dev, 4, "%s chan %d\n", __func__, vc->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001182 buffer = kzalloc(512, GFP_KERNEL);
1183 if (buffer == NULL) {
1184 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001185 return -ENOMEM;
1186 }
1187 /* form the get vid status command */
1188 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001189 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001190 buffer[2] = CMD_STATUS;
1191 *pstatus = 0;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001192 vc->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001193 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1194 kfree(buffer);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001195 wait_event_timeout(vc->wait_vidstatus,
1196 (vc->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001197 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001198 if (vc->vidstatus_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001199 dprintk(dev, 0, "s2255: no vidstatus response\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001200 res = -EFAULT;
1201 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001202 *pstatus = vc->vidstatus;
sensoray-devf5402002014-01-29 15:24:07 -03001203 dprintk(dev, 4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03001204 return res;
1205}
1206
Dean Anderson38f993a2008-06-26 23:15:51 -03001207static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1208{
1209 int res;
1210 struct s2255_fh *fh = priv;
1211 struct s2255_dev *dev = fh->dev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001212 struct s2255_vc *vc = fh->vc;
Dean Anderson38f993a2008-06-26 23:15:51 -03001213 int j;
sensoray-devf5402002014-01-29 15:24:07 -03001214 dprintk(dev, 4, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001215 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1216 dev_err(&dev->udev->dev, "invalid fh type0\n");
1217 return -EINVAL;
1218 }
1219 if (i != fh->type) {
1220 dev_err(&dev->udev->dev, "invalid fh type1\n");
1221 return -EINVAL;
1222 }
1223
Dean Andersonfe85ce92010-06-01 19:12:07 -03001224 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001225 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001226 return -EBUSY;
1227 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001228 vc->last_frame = -1;
1229 vc->bad_payload = 0;
1230 vc->cur_frame = 0;
1231 vc->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001232 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001233 vc->buffer.frame[j].ulState = S2255_READ_IDLE;
1234 vc->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001235 }
1236 res = videobuf_streamon(&fh->vb_vidq);
1237 if (res == 0) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001238 s2255_start_acquire(vc);
1239 vc->b_acquire = 1;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001240 } else
1241 res_free(fh);
1242
Dean Anderson38f993a2008-06-26 23:15:51 -03001243 return res;
1244}
1245
1246static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1247{
Dean Anderson38f993a2008-06-26 23:15:51 -03001248 struct s2255_fh *fh = priv;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001249 dprintk(fh->dev, 4, "%s\n, channel: %d", __func__, fh->vc->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001250 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
sensoray-devf5402002014-01-29 15:24:07 -03001251 dprintk(fh->dev, 1, "invalid fh type0\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001252 return -EINVAL;
1253 }
sensoray-devf5402002014-01-29 15:24:07 -03001254 if (i != fh->type)
Dean Anderson38f993a2008-06-26 23:15:51 -03001255 return -EINVAL;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001256 s2255_stop_acquire(fh->vc);
Dean Andersonb7732a32009-03-30 11:59:56 -03001257 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001258 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001259 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001260}
1261
Hans Verkuil314527a2013-03-15 06:10:40 -03001262static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i)
Dean Anderson38f993a2008-06-26 23:15:51 -03001263{
1264 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001265 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001266 struct videobuf_queue *q = &fh->vb_vidq;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001267 struct s2255_vc *vc = fh->vc;
Dean Anderson38f993a2008-06-26 23:15:51 -03001268 int ret = 0;
Hans Verkuil469af772013-02-15 06:12:58 -03001269
Dean Anderson38f993a2008-06-26 23:15:51 -03001270 mutex_lock(&q->vb_lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001271 if (res_locked(fh)) {
sensoray-devf5402002014-01-29 15:24:07 -03001272 dprintk(fh->dev, 1, "can't change standard after started\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001273 ret = -EBUSY;
1274 goto out_s_std;
1275 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001276 mode = fh->vc->mode;
Hans Verkuil314527a2013-03-15 06:10:40 -03001277 if (i & V4L2_STD_525_60) {
sensoray-devf5402002014-01-29 15:24:07 -03001278 dprintk(fh->dev, 4, "%s 60 Hz\n", __func__);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001279 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001280 if (mode.format != FORMAT_NTSC) {
1281 mode.restart = 1;
1282 mode.format = FORMAT_NTSC;
1283 mode.fdec = FDEC_1;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001284 vc->width = LINE_SZ_4CIFS_NTSC;
1285 vc->height = NUM_LINES_4CIFS_NTSC * 2;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001286 }
Hans Verkuil314527a2013-03-15 06:10:40 -03001287 } else if (i & V4L2_STD_625_50) {
sensoray-devf5402002014-01-29 15:24:07 -03001288 dprintk(fh->dev, 4, "%s 50 Hz\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001289 if (mode.format != FORMAT_PAL) {
1290 mode.restart = 1;
1291 mode.format = FORMAT_PAL;
1292 mode.fdec = FDEC_1;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001293 vc->width = LINE_SZ_4CIFS_PAL;
1294 vc->height = NUM_LINES_4CIFS_PAL * 2;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001295 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001296 } else {
1297 ret = -EINVAL;
Hans Verkuil469af772013-02-15 06:12:58 -03001298 goto out_s_std;
Dean Anderson38f993a2008-06-26 23:15:51 -03001299 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001300 fh->vc->std = i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001301 if (mode.restart)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001302 s2255_set_mode(fh->vc, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001303out_s_std:
1304 mutex_unlock(&q->vb_lock);
1305 return ret;
1306}
1307
Hans Verkuil469af772013-02-15 06:12:58 -03001308static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *i)
1309{
1310 struct s2255_fh *fh = priv;
1311
Dean Anderson5e950fa2014-02-04 18:16:24 -03001312 *i = fh->vc->std;
Hans Verkuil469af772013-02-15 06:12:58 -03001313 return 0;
1314}
1315
Dean Anderson38f993a2008-06-26 23:15:51 -03001316/* Sensoray 2255 is a multiple channel capture device.
1317 It does not have a "crossbar" of inputs.
1318 We use one V4L device per channel. The user must
1319 be aware that certain combinations are not allowed.
1320 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1321 at once in color(you can do full fps on 4 channels with greyscale.
1322*/
1323static int vidioc_enum_input(struct file *file, void *priv,
1324 struct v4l2_input *inp)
1325{
Dean Anderson4de39f52010-03-03 19:39:19 -03001326 struct s2255_fh *fh = priv;
1327 struct s2255_dev *dev = fh->dev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001328 struct s2255_vc *vc = fh->vc;
Dean Anderson4de39f52010-03-03 19:39:19 -03001329 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001330 if (inp->index != 0)
1331 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001332 inp->type = V4L2_INPUT_TYPE_CAMERA;
1333 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001334 inp->status = 0;
1335 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1336 int rc;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001337 rc = s2255_cmd_status(fh->vc, &status);
sensoray-devf5402002014-01-29 15:24:07 -03001338 dprintk(dev, 4, "s2255_cmd_status rc: %d status %x\n",
1339 rc, status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001340 if (rc == 0)
1341 inp->status = (status & 0x01) ? 0
1342 : V4L2_IN_ST_NO_SIGNAL;
1343 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001344 switch (dev->pid) {
1345 case 0x2255:
1346 default:
1347 strlcpy(inp->name, "Composite", sizeof(inp->name));
1348 break;
1349 case 0x2257:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001350 strlcpy(inp->name, (vc->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001351 sizeof(inp->name));
1352 break;
1353 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001354 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001355}
1356
1357static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1358{
1359 *i = 0;
1360 return 0;
1361}
1362static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1363{
1364 if (i > 0)
1365 return -EINVAL;
1366 return 0;
1367}
1368
Hans Verkuil192f1e72013-02-15 05:51:21 -03001369static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
Dean Anderson38f993a2008-06-26 23:15:51 -03001370{
Dean Anderson5e950fa2014-02-04 18:16:24 -03001371 struct s2255_vc *vc =
1372 container_of(ctrl->handler, struct s2255_vc, hdl);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001373 struct s2255_mode mode;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001374 mode = vc->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001375 /* update the mode to the corresponding value */
1376 switch (ctrl->id) {
1377 case V4L2_CID_BRIGHTNESS:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001378 mode.bright = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001379 break;
1380 case V4L2_CID_CONTRAST:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001381 mode.contrast = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001382 break;
1383 case V4L2_CID_HUE:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001384 mode.hue = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001385 break;
1386 case V4L2_CID_SATURATION:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001387 mode.saturation = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001388 break;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001389 case V4L2_CID_S2255_COLORFILTER:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001390 mode.color &= ~MASK_INPUT_TYPE;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001391 mode.color |= !ctrl->val << 16;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001392 break;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001393 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001394 vc->jpegqual = ctrl->val;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001395 return 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001396 default:
1397 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001398 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001399 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001400 /* set mode here. Note: stream does not need restarted.
1401 some V4L programs restart stream unnecessarily
1402 after a s_crtl.
1403 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001404 s2255_set_mode(vc, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001405 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001406}
1407
Dean Anderson22b88d42008-08-29 15:33:19 -03001408static int vidioc_g_jpegcomp(struct file *file, void *priv,
1409 struct v4l2_jpegcompression *jc)
1410{
1411 struct s2255_fh *fh = priv;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001412 struct s2255_vc *vc = fh->vc;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001413
1414 memset(jc, 0, sizeof(*jc));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001415 jc->quality = vc->jpegqual;
sensoray-devf5402002014-01-29 15:24:07 -03001416 dprintk(fh->dev, 2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001417 return 0;
1418}
1419
1420static int vidioc_s_jpegcomp(struct file *file, void *priv,
Hans Verkuild88aab52012-09-17 05:05:25 -03001421 const struct v4l2_jpegcompression *jc)
Dean Anderson22b88d42008-08-29 15:33:19 -03001422{
1423 struct s2255_fh *fh = priv;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001424 struct s2255_vc *vc = fh->vc;
Dean Anderson22b88d42008-08-29 15:33:19 -03001425 if (jc->quality < 0 || jc->quality > 100)
1426 return -EINVAL;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001427 v4l2_ctrl_s_ctrl(vc->jpegqual_ctrl, jc->quality);
sensoray-devf5402002014-01-29 15:24:07 -03001428 dprintk(fh->dev, 2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001429 return 0;
1430}
Dean Anderson7d853532009-05-15 14:32:04 -03001431
1432static int vidioc_g_parm(struct file *file, void *priv,
1433 struct v4l2_streamparm *sp)
1434{
1435 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001436 __u32 def_num, def_dem;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001437 struct s2255_vc *vc = fh->vc;
Dean Anderson7d853532009-05-15 14:32:04 -03001438 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1439 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001440 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001441 sp->parm.capture.capturemode = vc->cap_parm.capturemode;
1442 def_num = (vc->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1443 def_dem = (vc->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001444 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001445 switch (vc->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001446 default:
1447 case FDEC_1:
1448 sp->parm.capture.timeperframe.numerator = def_num;
1449 break;
1450 case FDEC_2:
1451 sp->parm.capture.timeperframe.numerator = def_num * 2;
1452 break;
1453 case FDEC_3:
1454 sp->parm.capture.timeperframe.numerator = def_num * 3;
1455 break;
1456 case FDEC_5:
1457 sp->parm.capture.timeperframe.numerator = def_num * 5;
1458 break;
1459 }
sensoray-devf5402002014-01-29 15:24:07 -03001460 dprintk(fh->dev, 4, "%s capture mode, %d timeperframe %d/%d\n",
1461 __func__,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001462 sp->parm.capture.capturemode,
1463 sp->parm.capture.timeperframe.numerator,
1464 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001465 return 0;
1466}
1467
1468static int vidioc_s_parm(struct file *file, void *priv,
1469 struct v4l2_streamparm *sp)
1470{
1471 struct s2255_fh *fh = priv;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001472 struct s2255_vc *vc = fh->vc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001473 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001474 int fdec = FDEC_1;
1475 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001476 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1477 return -EINVAL;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001478 mode = vc->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001479 /* high quality capture mode requires a stream restart */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001480 if (vc->cap_parm.capturemode
Dean Andersonfe85ce92010-06-01 19:12:07 -03001481 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001482 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001483 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1484 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001485 if (def_dem != sp->parm.capture.timeperframe.denominator)
1486 sp->parm.capture.timeperframe.numerator = def_num;
1487 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1488 sp->parm.capture.timeperframe.numerator = def_num;
1489 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1490 sp->parm.capture.timeperframe.numerator = def_num * 2;
1491 fdec = FDEC_2;
1492 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1493 sp->parm.capture.timeperframe.numerator = def_num * 3;
1494 fdec = FDEC_3;
1495 } else {
1496 sp->parm.capture.timeperframe.numerator = def_num * 5;
1497 fdec = FDEC_5;
1498 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001499 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001500 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001501 s2255_set_mode(vc, &mode);
sensoray-devf5402002014-01-29 15:24:07 -03001502 dprintk(fh->dev, 4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
Dean Andersone6b44bc2010-03-08 20:04:48 -03001503 __func__,
1504 sp->parm.capture.capturemode,
1505 sp->parm.capture.timeperframe.numerator,
1506 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001507 return 0;
1508}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001509
Hans Verkuil05e5d442013-02-15 06:09:18 -03001510#define NUM_SIZE_ENUMS 3
1511static const struct v4l2_frmsize_discrete ntsc_sizes[] = {
1512 { 640, 480 },
1513 { 640, 240 },
1514 { 320, 240 },
1515};
1516static const struct v4l2_frmsize_discrete pal_sizes[] = {
1517 { 704, 576 },
1518 { 704, 288 },
1519 { 352, 288 },
1520};
1521
1522static int vidioc_enum_framesizes(struct file *file, void *priv,
1523 struct v4l2_frmsizeenum *fe)
1524{
1525 struct s2255_fh *fh = priv;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001526 struct s2255_vc *vc = fh->vc;
1527 int is_ntsc = vc->std & V4L2_STD_525_60;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001528 const struct s2255_fmt *fmt;
1529
1530 if (fe->index >= NUM_SIZE_ENUMS)
1531 return -EINVAL;
1532
1533 fmt = format_by_fourcc(fe->pixel_format);
1534 if (fmt == NULL)
1535 return -EINVAL;
1536 fe->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1537 fe->discrete = is_ntsc ? ntsc_sizes[fe->index] : pal_sizes[fe->index];
1538 return 0;
1539}
1540
Dean Andersone6b44bc2010-03-08 20:04:48 -03001541static int vidioc_enum_frameintervals(struct file *file, void *priv,
1542 struct v4l2_frmivalenum *fe)
1543{
Hans Verkuil05e5d442013-02-15 06:09:18 -03001544 struct s2255_fh *fh = priv;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001545 struct s2255_vc *vc = fh->vc;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001546 const struct s2255_fmt *fmt;
1547 const struct v4l2_frmsize_discrete *sizes;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001548 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001549#define NUM_FRAME_ENUMS 4
1550 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
Hans Verkuil05e5d442013-02-15 06:09:18 -03001551 int i;
1552
Mauro Carvalho Chehab199ab8f2012-10-27 16:29:34 -03001553 if (fe->index >= NUM_FRAME_ENUMS)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001554 return -EINVAL;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001555
1556 fmt = format_by_fourcc(fe->pixel_format);
1557 if (fmt == NULL)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001558 return -EINVAL;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001559
1560 sizes = is_ntsc ? ntsc_sizes : pal_sizes;
1561 for (i = 0; i < NUM_SIZE_ENUMS; i++, sizes++)
1562 if (fe->width == sizes->width &&
1563 fe->height == sizes->height)
1564 break;
1565 if (i == NUM_SIZE_ENUMS)
1566 return -EINVAL;
1567
Dean Andersone6b44bc2010-03-08 20:04:48 -03001568 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1569 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1570 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
sensoray-devf5402002014-01-29 15:24:07 -03001571 dprintk(fh->dev, 4, "%s discrete %d/%d\n", __func__,
1572 fe->discrete.numerator,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001573 fe->discrete.denominator);
1574 return 0;
1575}
1576
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001577static int __s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001578{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001579 struct video_device *vdev = video_devdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001580 struct s2255_vc *vc = video_drvdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001581 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001582 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001583 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001584 int state;
sensoray-devf5402002014-01-29 15:24:07 -03001585 dprintk(dev, 1, "s2255: open called (dev=%s)\n",
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001586 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001587 state = atomic_read(&dev->fw_data->fw_state);
1588 switch (state) {
1589 case S2255_FW_DISCONNECTING:
Dean Andersonff7e22d2010-04-08 23:38:07 -03001590 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001591 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001592 s2255_dev_err(&dev->udev->dev,
1593 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001594 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001595 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001596 ((atomic_read(&dev->fw_data->fw_state)
1597 == S2255_FW_SUCCESS) ||
1598 (atomic_read(&dev->fw_data->fw_state)
1599 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001600 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001601 /* state may have changed, re-read */
1602 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001603 break;
1604 case S2255_FW_NOTLOADED:
1605 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001606 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1607 driver loaded and then device immediately opened */
sensoray-devf5402002014-01-29 15:24:07 -03001608 pr_info("%s waiting for firmware load\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001609 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001610 ((atomic_read(&dev->fw_data->fw_state)
1611 == S2255_FW_SUCCESS) ||
1612 (atomic_read(&dev->fw_data->fw_state)
1613 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001614 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001615 /* state may have changed, re-read */
1616 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001617 break;
1618 case S2255_FW_SUCCESS:
1619 default:
1620 break;
1621 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001622 /* state may have changed in above switch statement */
1623 switch (state) {
1624 case S2255_FW_SUCCESS:
1625 break;
1626 case S2255_FW_FAILED:
sensoray-devf5402002014-01-29 15:24:07 -03001627 pr_info("2255 firmware load failed.\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03001628 return -ENODEV;
1629 case S2255_FW_DISCONNECTING:
sensoray-devf5402002014-01-29 15:24:07 -03001630 pr_info("%s: disconnecting\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001631 return -ENODEV;
1632 case S2255_FW_LOADED_DSPWAIT:
1633 case S2255_FW_NOTLOADED:
sensoray-devf5402002014-01-29 15:24:07 -03001634 pr_info("%s: firmware not loaded, please retry\n",
1635 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001636 /*
1637 * Timeout on firmware load means device unusable.
1638 * Set firmware failure state.
1639 * On next s2255_open the firmware will be reloaded.
1640 */
1641 atomic_set(&dev->fw_data->fw_state,
1642 S2255_FW_FAILED);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001643 return -EAGAIN;
1644 default:
sensoray-devf5402002014-01-29 15:24:07 -03001645 pr_info("%s: unknown state\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001646 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001647 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001648 /* allocate + initialize per filehandle data */
1649 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001650 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001651 return -ENOMEM;
Hans Verkuil44d06d82013-02-15 05:59:00 -03001652 v4l2_fh_init(&fh->fh, vdev);
1653 v4l2_fh_add(&fh->fh);
1654 file->private_data = &fh->fh;
Dean Anderson38f993a2008-06-26 23:15:51 -03001655 fh->dev = dev;
1656 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001657 fh->vc = vc;
1658 if (!vc->configured) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001659 /* configure channel to default state */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001660 vc->fmt = &formats[0];
1661 s2255_set_mode(vc, &vc->mode);
1662 vc->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001663 }
sensoray-devf5402002014-01-29 15:24:07 -03001664 dprintk(dev, 1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001665 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Andersond86c6a82014-02-04 17:18:03 -03001666 dprintk(dev, 2, "%s: fh=0x%08lx, dev=0x%08lx\n", __func__,
1667 (unsigned long)fh, (unsigned long)dev);
sensoray-devf5402002014-01-29 15:24:07 -03001668 dprintk(dev, 4, "%s: list_empty active=%d\n", __func__,
Dean Anderson5e950fa2014-02-04 18:16:24 -03001669 list_empty(&vc->buf_list));
Dean Anderson38f993a2008-06-26 23:15:51 -03001670 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1671 NULL, &dev->slock,
1672 fh->type,
1673 V4L2_FIELD_INTERLACED,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001674 sizeof(struct s2255_buffer),
1675 fh, vdev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001676 return 0;
1677}
1678
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001679static int s2255_open(struct file *file)
1680{
1681 struct video_device *vdev = video_devdata(file);
1682 int ret;
1683
1684 if (mutex_lock_interruptible(vdev->lock))
1685 return -ERESTARTSYS;
1686 ret = __s2255_open(file);
1687 mutex_unlock(vdev->lock);
1688 return ret;
1689}
Dean Anderson38f993a2008-06-26 23:15:51 -03001690
1691static unsigned int s2255_poll(struct file *file,
1692 struct poll_table_struct *wait)
1693{
1694 struct s2255_fh *fh = file->private_data;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001695 struct s2255_dev *dev = fh->dev;
Hans Verkuil44d06d82013-02-15 05:59:00 -03001696 int rc = v4l2_ctrl_poll(file, wait);
1697
sensoray-devf5402002014-01-29 15:24:07 -03001698 dprintk(dev, 100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001699 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1700 return POLLERR;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001701 mutex_lock(&dev->lock);
Hans Verkuil44d06d82013-02-15 05:59:00 -03001702 rc |= videobuf_poll_stream(file, &fh->vb_vidq, wait);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001703 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001704 return rc;
1705}
1706
Dean Andersond62e85a2010-04-09 19:54:26 -03001707static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001708{
sensoray-devf5402002014-01-29 15:24:07 -03001709 dprintk(dev, 1, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001710 /* board shutdown stops the read pipe if it is running */
1711 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001712 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001713 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001714 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001715 usb_kill_urb(dev->fw_data->fw_urb);
1716 usb_free_urb(dev->fw_data->fw_urb);
1717 dev->fw_data->fw_urb = NULL;
1718 }
Jesper Juhl3fc82fa2012-04-09 16:50:04 -03001719 release_firmware(dev->fw_data->fw);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001720 kfree(dev->fw_data->pfw_data);
1721 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001722 /* reset the DSP so firmware can be reloaded next time */
1723 s2255_reset_dsppower(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001724 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001725 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001726 v4l2_device_unregister(&dev->v4l2_dev);
Dean Andersonb7732a32009-03-30 11:59:56 -03001727 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001728}
1729
Dean Andersonff7e22d2010-04-08 23:38:07 -03001730static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001731{
1732 struct s2255_fh *fh = file->private_data;
1733 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001734 struct video_device *vdev = video_devdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001735 struct s2255_vc *vc = fh->vc;
Dean Anderson38f993a2008-06-26 23:15:51 -03001736 if (!dev)
1737 return -ENODEV;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001738 mutex_lock(&dev->lock);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001739 /* turn off stream */
1740 if (res_check(fh)) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001741 if (vc->b_acquire)
1742 s2255_stop_acquire(fh->vc);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001743 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001744 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001745 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001746 videobuf_mmap_free(&fh->vb_vidq);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001747 mutex_unlock(&dev->lock);
sensoray-devf5402002014-01-29 15:24:07 -03001748 dprintk(dev, 1, "%s[%s]\n", __func__, video_device_node_name(vdev));
Hans Verkuil44d06d82013-02-15 05:59:00 -03001749 v4l2_fh_del(&fh->fh);
1750 v4l2_fh_exit(&fh->fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001751 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001752 return 0;
1753}
1754
1755static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1756{
1757 struct s2255_fh *fh = file->private_data;
Julia Lawalle8397762012-08-14 11:49:46 -03001758 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001759 int ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001760 if (!fh)
1761 return -ENODEV;
Julia Lawalle8397762012-08-14 11:49:46 -03001762 dev = fh->dev;
sensoray-devf5402002014-01-29 15:24:07 -03001763 dprintk(dev, 4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001764 if (mutex_lock_interruptible(&dev->lock))
1765 return -ERESTARTSYS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001766 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001767 mutex_unlock(&dev->lock);
sensoray-devf5402002014-01-29 15:24:07 -03001768 dprintk(dev, 4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001769 (unsigned long)vma->vm_start,
1770 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001771 return ret;
1772}
1773
Hans Verkuilbec43662008-12-30 06:58:20 -03001774static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001775 .owner = THIS_MODULE,
1776 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001777 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001778 .poll = s2255_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001779 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001780 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001781};
1782
Hans Verkuila3998102008-07-21 02:57:38 -03001783static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001784 .vidioc_querycap = vidioc_querycap,
1785 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1786 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1787 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1788 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1789 .vidioc_reqbufs = vidioc_reqbufs,
1790 .vidioc_querybuf = vidioc_querybuf,
1791 .vidioc_qbuf = vidioc_qbuf,
1792 .vidioc_dqbuf = vidioc_dqbuf,
1793 .vidioc_s_std = vidioc_s_std,
Hans Verkuil469af772013-02-15 06:12:58 -03001794 .vidioc_g_std = vidioc_g_std,
Dean Anderson38f993a2008-06-26 23:15:51 -03001795 .vidioc_enum_input = vidioc_enum_input,
1796 .vidioc_g_input = vidioc_g_input,
1797 .vidioc_s_input = vidioc_s_input,
Dean Anderson38f993a2008-06-26 23:15:51 -03001798 .vidioc_streamon = vidioc_streamon,
1799 .vidioc_streamoff = vidioc_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001800 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1801 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001802 .vidioc_s_parm = vidioc_s_parm,
1803 .vidioc_g_parm = vidioc_g_parm,
Hans Verkuil05e5d442013-02-15 06:09:18 -03001804 .vidioc_enum_framesizes = vidioc_enum_framesizes,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001805 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuil44d06d82013-02-15 05:59:00 -03001806 .vidioc_log_status = v4l2_ctrl_log_status,
1807 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1808 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001809};
1810
Dean Andersonff7e22d2010-04-08 23:38:07 -03001811static void s2255_video_device_release(struct video_device *vdev)
1812{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001813 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001814 struct s2255_vc *vc =
1815 container_of(vdev, struct s2255_vc, vdev);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001816
sensoray-devf5402002014-01-29 15:24:07 -03001817 dprintk(dev, 4, "%s, chnls: %d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001818 atomic_read(&dev->num_channels));
Hans Verkuil192f1e72013-02-15 05:51:21 -03001819
Dean Anderson5e950fa2014-02-04 18:16:24 -03001820 v4l2_ctrl_handler_free(&vc->hdl);
sensoray-devf5402002014-01-29 15:24:07 -03001821
Dean Andersonfe85ce92010-06-01 19:12:07 -03001822 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001823 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001824 return;
1825}
1826
Hans Verkuila3998102008-07-21 02:57:38 -03001827static struct video_device template = {
1828 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001829 .fops = &s2255_fops_v4l,
1830 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001831 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001832 .tvnorms = S2255_NORMS,
Dean Anderson38f993a2008-06-26 23:15:51 -03001833};
1834
Hans Verkuil192f1e72013-02-15 05:51:21 -03001835static const struct v4l2_ctrl_ops s2255_ctrl_ops = {
1836 .s_ctrl = s2255_s_ctrl,
1837};
1838
1839static const struct v4l2_ctrl_config color_filter_ctrl = {
1840 .ops = &s2255_ctrl_ops,
1841 .name = "Color Filter",
1842 .id = V4L2_CID_S2255_COLORFILTER,
1843 .type = V4L2_CTRL_TYPE_BOOLEAN,
1844 .max = 1,
1845 .step = 1,
1846 .def = 1,
1847};
1848
Dean Anderson38f993a2008-06-26 23:15:51 -03001849static int s2255_probe_v4l(struct s2255_dev *dev)
1850{
1851 int ret;
1852 int i;
1853 int cur_nr = video_nr;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001854 struct s2255_vc *vc;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001855 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1856 if (ret)
1857 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001858 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001859 /* register 4 video devices */
1860 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001861 vc = &dev->vc[i];
1862 INIT_LIST_HEAD(&vc->buf_list);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001863
Dean Anderson5e950fa2014-02-04 18:16:24 -03001864 v4l2_ctrl_handler_init(&vc->hdl, 6);
1865 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001866 V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001867 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001868 V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001869 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001870 V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001871 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001872 V4L2_CID_HUE, 0, 255, 1, DEF_HUE);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001873 vc->jpegqual_ctrl = v4l2_ctrl_new_std(&vc->hdl,
Hans Verkuil7041dec2013-02-15 05:53:45 -03001874 &s2255_ctrl_ops,
1875 V4L2_CID_JPEG_COMPRESSION_QUALITY,
1876 0, 100, 1, S2255_DEF_JPEG_QUAL);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001877 if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER &&
Dean Anderson5e950fa2014-02-04 18:16:24 -03001878 (dev->pid != 0x2257 || vc->idx <= 1))
1879 v4l2_ctrl_new_custom(&vc->hdl, &color_filter_ctrl,
sensoray-devf5402002014-01-29 15:24:07 -03001880 NULL);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001881 if (vc->hdl.error) {
1882 ret = vc->hdl.error;
1883 v4l2_ctrl_handler_free(&vc->hdl);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001884 dev_err(&dev->udev->dev, "couldn't register control\n");
1885 break;
1886 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001887 /* register 4 video devices */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001888 vc->vdev = template;
1889 vc->vdev.ctrl_handler = &vc->hdl;
1890 vc->vdev.lock = &dev->lock;
1891 vc->vdev.v4l2_dev = &dev->v4l2_dev;
1892 set_bit(V4L2_FL_USE_FH_PRIO, &vc->vdev.flags);
1893 video_set_drvdata(&vc->vdev, vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03001894 if (video_nr == -1)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001895 ret = video_register_device(&vc->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001896 VFL_TYPE_GRABBER,
1897 video_nr);
1898 else
Dean Anderson5e950fa2014-02-04 18:16:24 -03001899 ret = video_register_device(&vc->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001900 VFL_TYPE_GRABBER,
1901 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001902
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001903 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001904 dev_err(&dev->udev->dev,
1905 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001906 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001907 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001908 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001909 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Anderson5e950fa2014-02-04 18:16:24 -03001910 video_device_node_name(&vc->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001911
Dean Anderson38f993a2008-06-26 23:15:51 -03001912 }
sensoray-devf5402002014-01-29 15:24:07 -03001913 pr_info("Sensoray 2255 V4L driver Revision: %s\n",
1914 S2255_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001915 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001916 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001917 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001918 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001919 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001920 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
sensoray-devf5402002014-01-29 15:24:07 -03001921 pr_warn("s2255: Not all channels available.\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001922 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001923}
1924
Dean Anderson38f993a2008-06-26 23:15:51 -03001925/* this function moves the usb stream read pipe data
1926 * into the system buffers.
1927 * returns 0 on success, EAGAIN if more data to process( call this
1928 * function again).
1929 *
1930 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001931 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001932 * bytes 4-7: channel: 0-3
1933 * bytes 8-11: payload size: size of the frame
1934 * bytes 12-payloadsize+12: frame data
1935 */
1936static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1937{
Dean Anderson38f993a2008-06-26 23:15:51 -03001938 char *pdest;
1939 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001940 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001941 char *psrc;
1942 unsigned long copy_size;
1943 unsigned long size;
1944 s32 idx = -1;
1945 struct s2255_framei *frm;
1946 unsigned char *pdata;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001947 struct s2255_vc *vc;
sensoray-devf5402002014-01-29 15:24:07 -03001948 dprintk(dev, 100, "buffer to user\n");
Dean Anderson5e950fa2014-02-04 18:16:24 -03001949 vc = &dev->vc[dev->cc];
1950 idx = vc->cur_frame;
1951 frm = &vc->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001952 if (frm->ulState == S2255_READ_IDLE) {
1953 int jj;
1954 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03001955 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03001956 int payload;
1957 /* search for marker codes */
1958 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03001959 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03001960 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03001961 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03001962 case S2255_MARKER_FRAME:
sensoray-devf5402002014-01-29 15:24:07 -03001963 dprintk(dev, 4, "marker @ offset: %d [%x %x]\n",
1964 jj, pdata[0], pdata[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001965 offset = jj + PREFIX_SIZE;
1966 bframe = 1;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001967 cc = le32_to_cpu(pdword[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001968 if (cc >= MAX_CHANNELS) {
sensoray-devf5402002014-01-29 15:24:07 -03001969 dprintk(dev, 0,
1970 "bad channel\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001971 return -EINVAL;
1972 }
1973 /* reverse it */
1974 dev->cc = G_chnmap[cc];
Dean Anderson5e950fa2014-02-04 18:16:24 -03001975 vc = &dev->vc[dev->cc];
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001976 payload = le32_to_cpu(pdword[3]);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001977 if (payload > vc->req_image_size) {
1978 vc->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03001979 /* discard the bad frame */
1980 return -EINVAL;
1981 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001982 vc->pkt_size = payload;
1983 vc->jpg_size = le32_to_cpu(pdword[4]);
Dean Anderson14d96262008-08-25 13:58:55 -03001984 break;
1985 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001986
Dean Anderson14d96262008-08-25 13:58:55 -03001987 pdata += DEF_USB_BLOCK;
1988 jj += DEF_USB_BLOCK;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001989 if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001990 break;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001991 cc = G_chnmap[le32_to_cpu(pdword[1])];
Roel Kluinf14a2972009-10-23 07:59:42 -03001992 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001993 break;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001994 vc = &dev->vc[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03001995 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03001996 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03001997 /* check if channel valid */
1998 /* set mode ready */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001999 vc->setmode_ready = 1;
2000 wake_up(&vc->wait_setmode);
sensoray-devf5402002014-01-29 15:24:07 -03002001 dprintk(dev, 5, "setmode rdy %d\n", cc);
Dean Anderson14d96262008-08-25 13:58:55 -03002002 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002003 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002004 dev->chn_ready |= (1 << cc);
2005 if ((dev->chn_ready & 0x0f) != 0x0f)
2006 break;
2007 /* all channels ready */
sensoray-devf5402002014-01-29 15:24:07 -03002008 pr_info("s2255: fw loaded\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002009 atomic_set(&dev->fw_data->fw_state,
2010 S2255_FW_SUCCESS);
2011 wake_up(&dev->fw_data->wait_fw);
2012 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002013 case S2255_RESPONSE_STATUS:
Dean Anderson5e950fa2014-02-04 18:16:24 -03002014 vc->vidstatus = le32_to_cpu(pdword[3]);
2015 vc->vidstatus_ready = 1;
2016 wake_up(&vc->wait_vidstatus);
sensoray-devf5402002014-01-29 15:24:07 -03002017 dprintk(dev, 5, "vstat %x chan %d\n",
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002018 le32_to_cpu(pdword[3]), cc);
Dean Anderson4de39f52010-03-03 19:39:19 -03002019 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002020 default:
sensoray-devf5402002014-01-29 15:24:07 -03002021 pr_info("s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002022 }
2023 default:
2024 pdata++;
2025 break;
2026 }
2027 if (bframe)
2028 break;
2029 } /* for */
2030 if (!bframe)
2031 return -EINVAL;
2032 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03002033 vc = &dev->vc[dev->cc];
2034 idx = vc->cur_frame;
2035 frm = &vc->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002036 /* search done. now find out if should be acquiring on this channel */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002037 if (!vc->b_acquire) {
Dean Anderson14d96262008-08-25 13:58:55 -03002038 /* we found a frame, but this channel is turned off */
2039 frm->ulState = S2255_READ_IDLE;
2040 return -EINVAL;
2041 }
2042
2043 if (frm->ulState == S2255_READ_IDLE) {
2044 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002045 frm->cur_size = 0;
2046 }
2047
Dean Anderson14d96262008-08-25 13:58:55 -03002048 /* skip the marker 512 bytes (and offset if out of sync) */
2049 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2050
Dean Anderson38f993a2008-06-26 23:15:51 -03002051
2052 if (frm->lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03002053 dprintk(dev, 1, "s2255 frame buffer == NULL.%p %p %d %d",
Dean Anderson38f993a2008-06-26 23:15:51 -03002054 frm, dev, dev->cc, idx);
2055 return -ENOMEM;
2056 }
2057
2058 pdest = frm->lpvbits + frm->cur_size;
2059
Dean Anderson14d96262008-08-25 13:58:55 -03002060 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002061
Dean Anderson5e950fa2014-02-04 18:16:24 -03002062 size = vc->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002063
Dean Anderson14d96262008-08-25 13:58:55 -03002064 /* sanity check on pdest */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002065 if ((copy_size + frm->cur_size) < vc->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03002066 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002067
Dean Anderson38f993a2008-06-26 23:15:51 -03002068 frm->cur_size += copy_size;
sensoray-devf5402002014-01-29 15:24:07 -03002069 dprintk(dev, 4, "cur_size: %lu, size: %lu\n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002070
Dean Anderson14d96262008-08-25 13:58:55 -03002071 if (frm->cur_size >= size) {
sensoray-devf5402002014-01-29 15:24:07 -03002072 dprintk(dev, 2, "******[%d]Buffer[%d]full*******\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002073 dev->cc, idx);
Dean Anderson5e950fa2014-02-04 18:16:24 -03002074 vc->last_frame = vc->cur_frame;
2075 vc->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002076 /* end of system frame ring buffer, start at zero */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002077 if ((vc->cur_frame == SYS_FRAMES) ||
2078 (vc->cur_frame == vc->buffer.dwFrames))
2079 vc->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002080 /* frame ready */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002081 if (vc->b_acquire)
2082 s2255_got_frame(vc, vc->jpg_size);
2083 vc->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03002084 frm->ulState = S2255_READ_IDLE;
2085 frm->cur_size = 0;
2086
Dean Anderson38f993a2008-06-26 23:15:51 -03002087 }
2088 /* done successfully */
2089 return 0;
2090}
2091
2092static void s2255_read_video_callback(struct s2255_dev *dev,
2093 struct s2255_pipeinfo *pipe_info)
2094{
2095 int res;
sensoray-devf5402002014-01-29 15:24:07 -03002096 dprintk(dev, 50, "callback read video\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002097
2098 if (dev->cc >= MAX_CHANNELS) {
2099 dev->cc = 0;
2100 dev_err(&dev->udev->dev, "invalid channel\n");
2101 return;
2102 }
2103 /* otherwise copy to the system buffers */
2104 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002105 if (res != 0)
sensoray-devf5402002014-01-29 15:24:07 -03002106 dprintk(dev, 4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002107
sensoray-devf5402002014-01-29 15:24:07 -03002108 dprintk(dev, 50, "callback read video done\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002109 return;
2110}
2111
2112static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2113 u16 Index, u16 Value, void *TransferBuffer,
2114 s32 TransferBufferLength, int bOut)
2115{
2116 int r;
2117 if (!bOut) {
2118 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2119 Request,
2120 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2121 USB_DIR_IN,
2122 Value, Index, TransferBuffer,
2123 TransferBufferLength, HZ * 5);
2124 } else {
2125 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2126 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2127 Value, Index, TransferBuffer,
2128 TransferBufferLength, HZ * 5);
2129 }
2130 return r;
2131}
2132
2133/*
2134 * retrieve FX2 firmware version. future use.
2135 * @param dev pointer to device extension
2136 * @return -1 for fail, else returns firmware version as an int(16 bits)
2137 */
2138static int s2255_get_fx2fw(struct s2255_dev *dev)
2139{
2140 int fw;
2141 int ret;
2142 unsigned char transBuffer[64];
2143 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2144 S2255_VR_IN);
2145 if (ret < 0)
sensoray-devf5402002014-01-29 15:24:07 -03002146 dprintk(dev, 2, "get fw error: %x\n", ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03002147 fw = transBuffer[0] + (transBuffer[1] << 8);
sensoray-devf5402002014-01-29 15:24:07 -03002148 dprintk(dev, 2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002149 return fw;
2150}
2151
2152/*
2153 * Create the system ring buffer to copy frames into from the
2154 * usb read pipe.
2155 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002156static int s2255_create_sys_buffers(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03002157{
2158 unsigned long i;
2159 unsigned long reqsize;
Dean Anderson5e950fa2014-02-04 18:16:24 -03002160 vc->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03002161 /* always allocate maximum size(PAL) for system buffers */
2162 reqsize = SYS_FRAMES_MAXSIZE;
2163
2164 if (reqsize > SYS_FRAMES_MAXSIZE)
2165 reqsize = SYS_FRAMES_MAXSIZE;
2166
2167 for (i = 0; i < SYS_FRAMES; i++) {
2168 /* allocate the frames */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002169 vc->buffer.frame[i].lpvbits = vmalloc(reqsize);
2170 vc->buffer.frame[i].size = reqsize;
2171 if (vc->buffer.frame[i].lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03002172 pr_info("out of memory. using less frames\n");
Dean Anderson5e950fa2014-02-04 18:16:24 -03002173 vc->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002174 break;
2175 }
2176 }
2177
2178 /* make sure internal states are set */
2179 for (i = 0; i < SYS_FRAMES; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002180 vc->buffer.frame[i].ulState = 0;
2181 vc->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002182 }
2183
Dean Anderson5e950fa2014-02-04 18:16:24 -03002184 vc->cur_frame = 0;
2185 vc->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002186 return 0;
2187}
2188
Dean Anderson5e950fa2014-02-04 18:16:24 -03002189static int s2255_release_sys_buffers(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03002190{
2191 unsigned long i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002192 for (i = 0; i < SYS_FRAMES; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002193 if (vc->buffer.frame[i].lpvbits)
2194 vfree(vc->buffer.frame[i].lpvbits);
2195 vc->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002196 }
2197 return 0;
2198}
2199
2200static int s2255_board_init(struct s2255_dev *dev)
2201{
Dean Anderson38f993a2008-06-26 23:15:51 -03002202 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2203 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002204 int j;
2205 struct s2255_pipeinfo *pipe = &dev->pipe;
sensoray-devf5402002014-01-29 15:24:07 -03002206 dprintk(dev, 4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002207 memset(pipe, 0, sizeof(*pipe));
2208 pipe->dev = dev;
2209 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2210 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002211
Dean Andersonab85c6a2010-04-08 23:39:12 -03002212 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2213 GFP_KERNEL);
2214 if (pipe->transfer_buffer == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03002215 dprintk(dev, 1, "out of memory!\n");
Dean Andersonab85c6a2010-04-08 23:39:12 -03002216 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002217 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002218 /* query the firmware */
2219 fw_ver = s2255_get_fx2fw(dev);
2220
sensoray-devf5402002014-01-29 15:24:07 -03002221 pr_info("s2255: usb firmware version %d.%d\n",
2222 (fw_ver >> 8) & 0xff,
2223 fw_ver & 0xff);
Dean Andersonabce21f2009-04-23 16:04:41 -03002224
2225 if (fw_ver < S2255_CUR_USB_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002226 pr_info("s2255: newer USB firmware available\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002227
2228 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002229 struct s2255_vc *vc = &dev->vc[j];
2230 vc->b_acquire = 0;
2231 vc->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002232 if (dev->pid == 0x2257 && j > 1)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002233 vc->mode.color |= (1 << 16);
2234 vc->jpegqual = S2255_DEF_JPEG_QUAL;
2235 vc->width = LINE_SZ_4CIFS_NTSC;
2236 vc->height = NUM_LINES_4CIFS_NTSC * 2;
2237 vc->std = V4L2_STD_NTSC_M;
2238 vc->fmt = &formats[0];
2239 vc->mode.restart = 1;
2240 vc->req_image_size = get_transfer_size(&mode_def);
2241 vc->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002242 /* create the system buffers */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002243 s2255_create_sys_buffers(vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03002244 }
2245 /* start read pipe */
2246 s2255_start_readpipe(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002247 dprintk(dev, 1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002248 return 0;
2249}
2250
2251static int s2255_board_shutdown(struct s2255_dev *dev)
2252{
2253 u32 i;
sensoray-devf5402002014-01-29 15:24:07 -03002254 dprintk(dev, 1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002255
2256 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002257 if (dev->vc[i].b_acquire)
2258 s2255_stop_acquire(&dev->vc[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002259 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002260 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002261 for (i = 0; i < MAX_CHANNELS; i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002262 s2255_release_sys_buffers(&dev->vc[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002263 /* release transfer buffer */
2264 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002265 return 0;
2266}
2267
2268static void read_pipe_completion(struct urb *purb)
2269{
2270 struct s2255_pipeinfo *pipe_info;
2271 struct s2255_dev *dev;
2272 int status;
2273 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002274 pipe_info = purb->context;
Dean Anderson38f993a2008-06-26 23:15:51 -03002275 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002276 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002277 return;
2278 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002279 dev = pipe_info->dev;
2280 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002281 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002282 return;
2283 }
2284 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002285 /* if shutting down, do not resubmit, exit immediately */
2286 if (status == -ESHUTDOWN) {
sensoray-devf5402002014-01-29 15:24:07 -03002287 dprintk(dev, 2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002288 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002289 return;
2290 }
2291
2292 if (pipe_info->state == 0) {
sensoray-devf5402002014-01-29 15:24:07 -03002293 dprintk(dev, 2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002294 return;
2295 }
2296
Dean Andersonb02064c2009-04-30 12:29:38 -03002297 if (status == 0)
2298 s2255_read_video_callback(dev, pipe_info);
2299 else {
2300 pipe_info->err_count++;
sensoray-devf5402002014-01-29 15:24:07 -03002301 dprintk(dev, 1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002302 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002303
Dean Anderson38f993a2008-06-26 23:15:51 -03002304 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2305 /* reuse urb */
2306 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2307 pipe,
2308 pipe_info->transfer_buffer,
2309 pipe_info->cur_transfer_size,
2310 read_pipe_completion, pipe_info);
2311
2312 if (pipe_info->state != 0) {
sensoray-devf5402002014-01-29 15:24:07 -03002313 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC))
Dean Anderson38f993a2008-06-26 23:15:51 -03002314 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002315 } else {
sensoray-devf5402002014-01-29 15:24:07 -03002316 dprintk(dev, 2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002317 }
2318 return;
2319}
2320
2321static int s2255_start_readpipe(struct s2255_dev *dev)
2322{
2323 int pipe;
2324 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002325 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002326 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
sensoray-devf5402002014-01-29 15:24:07 -03002327 dprintk(dev, 2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002328 pipe_info->state = 1;
2329 pipe_info->err_count = 0;
2330 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2331 if (!pipe_info->stream_urb) {
2332 dev_err(&dev->udev->dev,
2333 "ReadStream: Unable to alloc URB\n");
2334 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002335 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002336 /* transfer buffer allocated in board_init */
2337 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2338 pipe,
2339 pipe_info->transfer_buffer,
2340 pipe_info->cur_transfer_size,
2341 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002342 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2343 if (retval) {
sensoray-devf5402002014-01-29 15:24:07 -03002344 pr_err("s2255: start read pipe failed\n");
Dean Andersonab85c6a2010-04-08 23:39:12 -03002345 return retval;
2346 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002347 return 0;
2348}
2349
2350/* starts acquisition process */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002351static int s2255_start_acquire(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03002352{
2353 unsigned char *buffer;
2354 int res;
2355 unsigned long chn_rev;
2356 int j;
Dean Anderson5e950fa2014-02-04 18:16:24 -03002357 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
2358 chn_rev = G_chnmap[vc->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002359 buffer = kzalloc(512, GFP_KERNEL);
2360 if (buffer == NULL) {
2361 dev_err(&dev->udev->dev, "out of mem\n");
2362 return -ENOMEM;
2363 }
2364
Dean Anderson5e950fa2014-02-04 18:16:24 -03002365 vc->last_frame = -1;
2366 vc->bad_payload = 0;
2367 vc->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002368 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002369 vc->buffer.frame[j].ulState = 0;
2370 vc->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002371 }
2372
2373 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002374 *(__le32 *) buffer = IN_DATA_TOKEN;
2375 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2376 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002377 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2378 if (res != 0)
2379 dev_err(&dev->udev->dev, "CMD_START error\n");
2380
Dean Anderson5e950fa2014-02-04 18:16:24 -03002381 dprintk(dev, 2, "start acquire exit[%d] %d\n", vc->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03002382 kfree(buffer);
2383 return 0;
2384}
2385
Dean Anderson5e950fa2014-02-04 18:16:24 -03002386static int s2255_stop_acquire(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03002387{
2388 unsigned char *buffer;
2389 int res;
2390 unsigned long chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03002391 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
2392 chn_rev = G_chnmap[vc->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002393 buffer = kzalloc(512, GFP_KERNEL);
2394 if (buffer == NULL) {
2395 dev_err(&dev->udev->dev, "out of mem\n");
2396 return -ENOMEM;
2397 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002398 /* send the stop command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002399 *(__le32 *) buffer = IN_DATA_TOKEN;
2400 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2401 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002402 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002403 if (res != 0)
2404 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002405 kfree(buffer);
Dean Anderson5e950fa2014-02-04 18:16:24 -03002406 vc->b_acquire = 0;
2407 dprintk(dev, 4, "%s: chn %d, res %d\n", __func__, vc->idx, res);
Dean Anderson14d96262008-08-25 13:58:55 -03002408 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002409}
2410
2411static void s2255_stop_readpipe(struct s2255_dev *dev)
2412{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002413 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002414
Dean Andersonab85c6a2010-04-08 23:39:12 -03002415 pipe->state = 0;
2416 if (pipe->stream_urb) {
2417 /* cancel urb */
2418 usb_kill_urb(pipe->stream_urb);
2419 usb_free_urb(pipe->stream_urb);
2420 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002421 }
sensoray-devf5402002014-01-29 15:24:07 -03002422 dprintk(dev, 4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002423 return;
2424}
2425
Dean Anderson14d96262008-08-25 13:58:55 -03002426static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002427{
Dean Anderson14d96262008-08-25 13:58:55 -03002428 if (reset)
2429 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002430 dev->fw_data->fw_size = dev->fw_data->fw->size;
2431 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2432 memcpy(dev->fw_data->pfw_data,
2433 dev->fw_data->fw->data, CHUNK_SIZE);
2434 dev->fw_data->fw_loaded = CHUNK_SIZE;
2435 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2436 usb_sndbulkpipe(dev->udev, 2),
2437 dev->fw_data->pfw_data,
2438 CHUNK_SIZE, s2255_fwchunk_complete,
2439 dev->fw_data);
2440 mod_timer(&dev->timer, jiffies + HZ);
2441}
2442
2443/* standard usb probe function */
2444static int s2255_probe(struct usb_interface *interface,
2445 const struct usb_device_id *id)
2446{
2447 struct s2255_dev *dev = NULL;
2448 struct usb_host_interface *iface_desc;
2449 struct usb_endpoint_descriptor *endpoint;
2450 int i;
2451 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002452 __le32 *pdata;
2453 int fw_size;
Dean Anderson38f993a2008-06-26 23:15:51 -03002454 /* allocate memory for our device state and initialize it to zero */
2455 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2456 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002457 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002458 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002459 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002460 atomic_set(&dev->num_channels, 0);
Hans Verkuil0b84caa2013-02-26 14:14:19 -03002461 dev->pid = le16_to_cpu(id->idProduct);
Dean Anderson38f993a2008-06-26 23:15:51 -03002462 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2463 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002464 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002465 mutex_init(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002466 /* grab usb_device and save it */
2467 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2468 if (dev->udev == NULL) {
2469 dev_err(&interface->dev, "null usb device\n");
2470 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002471 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002472 }
sensoray-devf5402002014-01-29 15:24:07 -03002473 dev_dbg(&interface->dev, "dev: %p, udev %p interface %p\n",
2474 dev, dev->udev, interface);
Dean Anderson38f993a2008-06-26 23:15:51 -03002475 dev->interface = interface;
2476 /* set up the endpoint information */
2477 iface_desc = interface->cur_altsetting;
sensoray-devf5402002014-01-29 15:24:07 -03002478 dev_dbg(&interface->dev, "num EP: %d\n",
2479 iface_desc->desc.bNumEndpoints);
Dean Anderson38f993a2008-06-26 23:15:51 -03002480 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2481 endpoint = &iface_desc->endpoint[i].desc;
2482 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2483 /* we found the bulk in endpoint */
2484 dev->read_endpoint = endpoint->bEndpointAddress;
2485 }
2486 }
2487
2488 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002489 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002490 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002491 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002492 init_timer(&dev->timer);
2493 dev->timer.function = s2255_timer;
2494 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002495 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002496 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002497 struct s2255_vc *vc = &dev->vc[i];
2498 vc->idx = i;
2499 vc->dev = dev;
2500 init_waitqueue_head(&vc->wait_setmode);
2501 init_waitqueue_head(&vc->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002502 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002503
2504 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002505 if (!dev->fw_data->fw_urb) {
2506 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002507 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002508 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002509
Dean Anderson38f993a2008-06-26 23:15:51 -03002510 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2511 if (!dev->fw_data->pfw_data) {
2512 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002513 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002514 }
2515 /* load the first chunk */
2516 if (request_firmware(&dev->fw_data->fw,
2517 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
sensoray-devf5402002014-01-29 15:24:07 -03002518 dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002519 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002520 }
Dean Anderson14d96262008-08-25 13:58:55 -03002521 /* check the firmware is valid */
2522 fw_size = dev->fw_data->fw->size;
2523 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002524
Dean Anderson14d96262008-08-25 13:58:55 -03002525 if (*pdata != S2255_FW_MARKER) {
sensoray-devf5402002014-01-29 15:24:07 -03002526 dev_err(&interface->dev, "Firmware invalid.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002527 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002528 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002529 } else {
2530 /* make sure firmware is the latest */
2531 __le32 *pRel;
2532 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
sensoray-devf5402002014-01-29 15:24:07 -03002533 pr_info("s2255 dsp fw version %x\n", le32_to_cpu(*pRel));
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002534 dev->dsp_fw_ver = le32_to_cpu(*pRel);
2535 if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002536 pr_info("s2255: f2255usb.bin out of date.\n");
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002537 if (dev->pid == 0x2257 &&
2538 dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
sensoray-devf5402002014-01-29 15:24:07 -03002539 pr_warn("2257 needs firmware %d or above.\n",
2540 S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002541 }
Dean Anderson14d96262008-08-25 13:58:55 -03002542 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002543 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002544 retval = s2255_board_init(dev);
2545 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002546 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002547 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002548 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002549 /* loads v4l specific */
2550 retval = s2255_probe_v4l(dev);
2551 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002552 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002553 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2554 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002555errorBOARDINIT:
2556 s2255_board_shutdown(dev);
2557errorFWMARKER:
2558 release_firmware(dev->fw_data->fw);
2559errorREQFW:
2560 kfree(dev->fw_data->pfw_data);
2561errorFWDATA2:
2562 usb_free_urb(dev->fw_data->fw_urb);
2563errorFWURB:
2564 del_timer(&dev->timer);
2565errorEP:
2566 usb_put_dev(dev->udev);
2567errorUDEV:
2568 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002569 mutex_destroy(&dev->lock);
2570errorFWDATA1:
2571 kfree(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002572 pr_warn("Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002573 return retval;
2574}
2575
2576/* disconnect routine. when board is removed physically or with rmmod */
2577static void s2255_disconnect(struct usb_interface *interface)
2578{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002579 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002580 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002581 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002582 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002583 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002584 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002585 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002586 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002587 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002588 for (i = 0; i < channels; i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002589 video_unregister_device(&dev->vc[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002590 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002591 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2592 wake_up(&dev->fw_data->wait_fw);
2593 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002594 dev->vc[i].setmode_ready = 1;
2595 wake_up(&dev->vc[i].wait_setmode);
2596 dev->vc[i].vidstatus_ready = 1;
2597 wake_up(&dev->vc[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002598 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002599 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002600 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002601 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002602}
2603
2604static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002605 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002606 .probe = s2255_probe,
2607 .disconnect = s2255_disconnect,
2608 .id_table = s2255_table,
2609};
2610
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002611module_usb_driver(s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002612
2613MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2614MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2615MODULE_LICENSE("GPL");
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03002616MODULE_VERSION(S2255_VERSION);
Tim Gardner1bec9822012-07-24 16:52:27 -03002617MODULE_FIRMWARE(FIRMWARE_FILE_NAME);