blob: ccc00099b26144e4bd1c5b99cbfccbf266a50ad7 [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>
sensoray-dev340a30c2014-02-12 17:25:45 -030048#include <media/videobuf2-vmalloc.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030049#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
sensoray-dev340a30c2014-02-12 17:25:45 -030055#define S2255_VERSION "1.25.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;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300232 /* allocated image size */
233 unsigned long req_image_size;
234 /* received packet size */
235 unsigned long pkt_size;
236 int bad_payload;
237 unsigned long frame_count;
238 /* if JPEG image */
239 int jpg_size;
240 /* if channel configured to default state */
241 int configured;
242 wait_queue_head_t wait_setmode;
243 int setmode_ready;
244 /* video status items */
245 int vidstatus;
246 wait_queue_head_t wait_vidstatus;
247 int vidstatus_ready;
248 unsigned int width;
249 unsigned int height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300250 enum v4l2_field field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300251 const struct s2255_fmt *fmt;
252 int idx; /* channel number on device, 0-3 */
sensoray-dev340a30c2014-02-12 17:25:45 -0300253 struct vb2_queue vb_vidq;
254 struct mutex vb_lock; /* streaming lock */
255 spinlock_t qlock;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300256};
257
Dean Anderson38f993a2008-06-26 23:15:51 -0300258
259struct s2255_dev {
Dean Anderson5e950fa2014-02-04 18:16:24 -0300260 struct s2255_vc vc[MAX_CHANNELS];
sensoray-devf5402002014-01-29 15:24:07 -0300261 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300262 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300263 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300264 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson47d8c882014-02-05 15:43:51 -0300265 struct mutex cmdlock; /* protects cmdbuf */
Dean Anderson38f993a2008-06-26 23:15:51 -0300266 struct usb_device *udev;
267 struct usb_interface *interface;
268 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300269 struct timer_list timer;
270 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300271 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300272 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300273 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300274 int chn_ready;
Dean Anderson4de39f52010-03-03 19:39:19 -0300275 /* dsp firmware version (f2255usb.bin) */
276 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300277 u16 pid; /* product id */
Dean Anderson47d8c882014-02-05 15:43:51 -0300278#define S2255_CMDBUF_SIZE 512
279 __le32 *cmdbuf;
Dean Anderson38f993a2008-06-26 23:15:51 -0300280};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300281
Dean Anderson65c6edb2010-04-20 17:21:32 -0300282static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
283{
284 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
285}
Dean Anderson38f993a2008-06-26 23:15:51 -0300286
287struct s2255_fmt {
288 char *name;
289 u32 fourcc;
290 int depth;
291};
292
293/* buffer for one video frame */
294struct s2255_buffer {
295 /* common v4l buffer stuff -- must be first */
sensoray-dev340a30c2014-02-12 17:25:45 -0300296 struct vb2_buffer vb;
297 struct list_head list;
Dean Anderson38f993a2008-06-26 23:15:51 -0300298};
299
Dean Anderson38f993a2008-06-26 23:15:51 -0300300
Dean Andersonabce21f2009-04-23 16:04:41 -0300301/* current cypress EEPROM firmware version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300302#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
Dean Anderson4de39f52010-03-03 19:39:19 -0300303/* current DSP FW version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300304#define S2255_CUR_DSP_FWVER 10104
Dean Anderson4de39f52010-03-03 19:39:19 -0300305/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300306#define S2255_MIN_DSP_STATUS 5
307#define S2255_MIN_DSP_COLORFILTER 8
Hans Verkuil469af772013-02-15 06:12:58 -0300308#define S2255_NORMS (V4L2_STD_ALL)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300309
310/* private V4L2 controls */
311
312/*
313 * The following chart displays how COLORFILTER should be set
314 * =========================================================
315 * = fourcc = COLORFILTER =
316 * = ===============================
317 * = = 0 = 1 =
318 * =========================================================
319 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
320 * = = s-video or = composite =
321 * = = B/W camera = input =
322 * =========================================================
323 * = other = color, svideo = color, =
324 * = = = composite =
325 * =========================================================
326 *
327 * Notes:
328 * channels 0-3 on 2255 are composite
329 * channels 0-1 on 2257 are composite, 2-3 are s-video
330 * If COLORFILTER is 0 with a composite color camera connected,
331 * the output will appear monochrome but hatching
332 * will occur.
333 * COLORFILTER is different from "color killer" and "color effects"
334 * for reasons above.
335 */
336#define S2255_V4L2_YC_ON 1
337#define S2255_V4L2_YC_OFF 0
Hans Verkuil192f1e72013-02-15 05:51:21 -0300338#define V4L2_CID_S2255_COLORFILTER (V4L2_CID_USER_S2255_BASE + 0)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300339
Dean Anderson38f993a2008-06-26 23:15:51 -0300340/* frame prefix size (sent once every frame) */
341#define PREFIX_SIZE 512
342
343/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300344static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300345
Dean Anderson38f993a2008-06-26 23:15:51 -0300346static int debug;
Dean Anderson38f993a2008-06-26 23:15:51 -0300347
348static int s2255_start_readpipe(struct s2255_dev *dev);
349static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300350static int s2255_start_acquire(struct s2255_vc *vc);
351static int s2255_stop_acquire(struct s2255_vc *vc);
352static void s2255_fillbuff(struct s2255_vc *vc, struct s2255_buffer *buf,
Dean Andersonfe85ce92010-06-01 19:12:07 -0300353 int jpgsize);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300354static int s2255_set_mode(struct s2255_vc *vc, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300355static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300356static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300357static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300358static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
359 u16 index, u16 value, void *buf,
360 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300361
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300362/* dev_err macro with driver name */
363#define S2255_DRIVER_NAME "s2255"
364#define s2255_dev_err(dev, fmt, arg...) \
365 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
366
sensoray-devf5402002014-01-29 15:24:07 -0300367#define dprintk(dev, level, fmt, arg...) \
368 v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
Dean Anderson38f993a2008-06-26 23:15:51 -0300369
Dean Anderson38f993a2008-06-26 23:15:51 -0300370static struct usb_driver s2255_driver;
371
Dean Anderson38f993a2008-06-26 23:15:51 -0300372/* start video number */
373static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
374
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300375/* Enable jpeg capture. */
376static int jpeg_enable = 1;
377
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300378module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300379MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300380module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300381MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300382module_param(jpeg_enable, int, 0644);
383MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
Dean Anderson38f993a2008-06-26 23:15:51 -0300384
385/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300386#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300387static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300388 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
389 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300390 { } /* Terminating entry */
391};
392MODULE_DEVICE_TABLE(usb, s2255_table);
393
Dean Anderson38f993a2008-06-26 23:15:51 -0300394#define BUFFER_TIMEOUT msecs_to_jiffies(400)
395
Dean Anderson38f993a2008-06-26 23:15:51 -0300396/* image formats. */
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300397/* JPEG formats must be defined last to support jpeg_enable parameter */
Dean Anderson38f993a2008-06-26 23:15:51 -0300398static const struct s2255_fmt formats[] = {
399 {
Dean Anderson38f993a2008-06-26 23:15:51 -0300400 .name = "4:2:2, packed, YUYV",
401 .fourcc = V4L2_PIX_FMT_YUYV,
402 .depth = 16
403
404 }, {
405 .name = "4:2:2, packed, UYVY",
406 .fourcc = V4L2_PIX_FMT_UYVY,
407 .depth = 16
408 }, {
Hans Verkuil5c632b22013-02-26 14:29:04 -0300409 .name = "4:2:2, planar, YUV422P",
410 .fourcc = V4L2_PIX_FMT_YUV422P,
411 .depth = 16
412
413 }, {
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300414 .name = "8bpp GREY",
415 .fourcc = V4L2_PIX_FMT_GREY,
416 .depth = 8
417 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300418 .name = "JPG",
419 .fourcc = V4L2_PIX_FMT_JPEG,
420 .depth = 24
421 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300422 .name = "MJPG",
423 .fourcc = V4L2_PIX_FMT_MJPEG,
424 .depth = 24
Dean Anderson38f993a2008-06-26 23:15:51 -0300425 }
426};
427
Dean Anderson5e950fa2014-02-04 18:16:24 -0300428static int norm_maxw(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300429{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300430 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300431 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
432}
433
Dean Anderson5e950fa2014-02-04 18:16:24 -0300434static int norm_maxh(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300435{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300436 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300437 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
438}
439
Dean Anderson5e950fa2014-02-04 18:16:24 -0300440static int norm_minw(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300441{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300442 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300443 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
444}
445
Dean Anderson5e950fa2014-02-04 18:16:24 -0300446static int norm_minh(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300447{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300448 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300449 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
450}
451
452
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300453/*
454 * TODO: fixme: move YUV reordering to hardware
455 * converts 2255 planar format to yuyv or uyvy
456 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300457static void planar422p_to_yuv_packed(const unsigned char *in,
458 unsigned char *out,
459 int width, int height,
460 int fmt)
461{
462 unsigned char *pY;
463 unsigned char *pCb;
464 unsigned char *pCr;
465 unsigned long size = height * width;
466 unsigned int i;
467 pY = (unsigned char *)in;
468 pCr = (unsigned char *)in + height * width;
469 pCb = (unsigned char *)in + height * width + (height * width / 2);
470 for (i = 0; i < size * 2; i += 4) {
471 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
472 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
473 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
474 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
475 }
476 return;
477}
478
Hans Verkuild45b9b82008-09-04 03:33:43 -0300479static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300480{
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300481 s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
sensoray-devf5402002014-01-29 15:24:07 -0300482 msleep(20);
Dean Anderson14d96262008-08-25 13:58:55 -0300483 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300484 msleep(600);
485 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300486 return;
487}
Dean Anderson38f993a2008-06-26 23:15:51 -0300488
489/* kickstarts the firmware loading. from probe
490 */
491static void s2255_timer(unsigned long user_data)
492{
493 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson38f993a2008-06-26 23:15:51 -0300494 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
sensoray-devf5402002014-01-29 15:24:07 -0300495 pr_err("s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300496 atomic_set(&data->fw_state, S2255_FW_FAILED);
497 /* wake up anything waiting for the firmware */
498 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300499 return;
500 }
501}
502
Dean Anderson38f993a2008-06-26 23:15:51 -0300503
504/* this loads the firmware asynchronously.
Hans Verkuil0b84caa2013-02-26 14:14:19 -0300505 Originally this was done synchronously in probe.
Dean Anderson38f993a2008-06-26 23:15:51 -0300506 But it is better to load it asynchronously here than block
507 inside the probe function. Blocking inside probe affects boot time.
508 FW loading is triggered by the timer in the probe function
509*/
510static void s2255_fwchunk_complete(struct urb *urb)
511{
512 struct s2255_fw *data = urb->context;
513 struct usb_device *udev = urb->dev;
514 int len;
Dean Anderson38f993a2008-06-26 23:15:51 -0300515 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300516 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300517 atomic_set(&data->fw_state, S2255_FW_FAILED);
518 /* wake up anything waiting for the firmware */
519 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300520 return;
521 }
522 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300523 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300524 atomic_set(&data->fw_state, S2255_FW_FAILED);
525 /* wake up anything waiting for the firmware */
526 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300527 return;
528 }
529#define CHUNK_SIZE 512
530 /* all USB transfers must be done with continuous kernel memory.
531 can't allocate more than 128k in current linux kernel, so
532 upload the firmware in chunks
533 */
534 if (data->fw_loaded < data->fw_size) {
535 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
536 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
537
538 if (len < CHUNK_SIZE)
539 memset(data->pfw_data, 0, CHUNK_SIZE);
540
Dean Anderson38f993a2008-06-26 23:15:51 -0300541 memcpy(data->pfw_data,
542 (char *) data->fw->data + data->fw_loaded, len);
543
544 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
545 data->pfw_data, CHUNK_SIZE,
546 s2255_fwchunk_complete, data);
547 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
548 dev_err(&udev->dev, "failed submit URB\n");
549 atomic_set(&data->fw_state, S2255_FW_FAILED);
550 /* wake up anything waiting for the firmware */
551 wake_up(&data->wait_fw);
552 return;
553 }
554 data->fw_loaded += len;
sensoray-devf5402002014-01-29 15:24:07 -0300555 } else
Dean Anderson38f993a2008-06-26 23:15:51 -0300556 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson38f993a2008-06-26 23:15:51 -0300557 return;
558
559}
560
Dean Anderson5e950fa2014-02-04 18:16:24 -0300561static int s2255_got_frame(struct s2255_vc *vc, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300562{
Dean Anderson38f993a2008-06-26 23:15:51 -0300563 struct s2255_buffer *buf;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300564 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300565 unsigned long flags = 0;
566 int rc = 0;
sensoray-dev340a30c2014-02-12 17:25:45 -0300567 spin_lock_irqsave(&vc->qlock, flags);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300568 if (list_empty(&vc->buf_list)) {
sensoray-devf5402002014-01-29 15:24:07 -0300569 dprintk(dev, 1, "No active queue to serve\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300570 rc = -1;
571 goto unlock;
572 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300573 buf = list_entry(vc->buf_list.next,
sensoray-dev340a30c2014-02-12 17:25:45 -0300574 struct s2255_buffer, list);
575 list_del(&buf->list);
576 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300577 s2255_fillbuff(vc, buf, jpgsize);
sensoray-dev340a30c2014-02-12 17:25:45 -0300578 dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf);
Dean Anderson38f993a2008-06-26 23:15:51 -0300579unlock:
sensoray-dev340a30c2014-02-12 17:25:45 -0300580 spin_unlock_irqrestore(&vc->qlock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300581 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300582}
583
Dean Anderson38f993a2008-06-26 23:15:51 -0300584static const struct s2255_fmt *format_by_fourcc(int fourcc)
585{
586 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300587 for (i = 0; i < ARRAY_SIZE(formats); i++) {
588 if (-1 == formats[i].fourcc)
589 continue;
sensoray-devf5402002014-01-29 15:24:07 -0300590 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
591 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
592 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300593 if (formats[i].fourcc == fourcc)
594 return formats + i;
595 }
596 return NULL;
597}
598
Dean Anderson38f993a2008-06-26 23:15:51 -0300599/* video buffer vmalloc implementation based partly on VIVI driver which is
600 * Copyright (c) 2006 by
601 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
602 * Ted Walther <ted--a.t--enumera.com>
603 * John Sokol <sokol--a.t--videotechnology.com>
604 * http://v4l.videotechnology.com/
605 *
606 */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300607static void s2255_fillbuff(struct s2255_vc *vc,
Dean Andersonfe85ce92010-06-01 19:12:07 -0300608 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300609{
610 int pos = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300611 const char *tmpbuf;
sensoray-dev340a30c2014-02-12 17:25:45 -0300612 char *vbuf = vb2_plane_vaddr(&buf->vb, 0);
Dean Anderson38f993a2008-06-26 23:15:51 -0300613 unsigned long last_frame;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300614 struct s2255_dev *dev = vc->dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300615
616 if (!vbuf)
617 return;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300618 last_frame = vc->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300619 if (last_frame != -1) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300620 tmpbuf =
Dean Anderson5e950fa2014-02-04 18:16:24 -0300621 (const char *)vc->buffer.frame[last_frame].lpvbits;
Dean Anderson8bf405a2014-02-05 15:18:55 -0300622 switch (vc->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300623 case V4L2_PIX_FMT_YUYV:
624 case V4L2_PIX_FMT_UYVY:
625 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
sensoray-dev340a30c2014-02-12 17:25:45 -0300626 vbuf, vc->width,
627 vc->height,
Dean Anderson8bf405a2014-02-05 15:18:55 -0300628 vc->fmt->fourcc);
Dean Anderson38f993a2008-06-26 23:15:51 -0300629 break;
630 case V4L2_PIX_FMT_GREY:
sensoray-dev340a30c2014-02-12 17:25:45 -0300631 memcpy(vbuf, tmpbuf, vc->width * vc->height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300632 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300633 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300634 case V4L2_PIX_FMT_MJPEG:
sensoray-dev340a30c2014-02-12 17:25:45 -0300635 buf->vb.v4l2_buf.length = jpgsize;
636 memcpy(vbuf, tmpbuf, jpgsize);
Dean Anderson14d96262008-08-25 13:58:55 -0300637 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300638 case V4L2_PIX_FMT_YUV422P:
639 memcpy(vbuf, tmpbuf,
sensoray-dev340a30c2014-02-12 17:25:45 -0300640 vc->width * vc->height * 2);
Dean Anderson38f993a2008-06-26 23:15:51 -0300641 break;
642 default:
sensoray-devf5402002014-01-29 15:24:07 -0300643 pr_info("s2255: unknown format?\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300644 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300645 vc->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300646 } else {
sensoray-devf5402002014-01-29 15:24:07 -0300647 pr_err("s2255: =======no frame\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300648 return;
Dean Anderson38f993a2008-06-26 23:15:51 -0300649 }
sensoray-devf5402002014-01-29 15:24:07 -0300650 dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n",
Dean Anderson38f993a2008-06-26 23:15:51 -0300651 (unsigned long)vbuf, pos);
652 /* tell v4l buffer was filled */
sensoray-dev340a30c2014-02-12 17:25:45 -0300653 buf->vb.v4l2_buf.field = vc->field;
654 buf->vb.v4l2_buf.sequence = vc->frame_count;
655 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
656 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
Dean Anderson38f993a2008-06-26 23:15:51 -0300657}
658
659
660/* ------------------------------------------------------------------
661 Videobuf operations
662 ------------------------------------------------------------------*/
663
sensoray-dev340a30c2014-02-12 17:25:45 -0300664static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
665 unsigned int *nbuffers, unsigned int *nplanes,
666 unsigned int sizes[], void *alloc_ctxs[])
Dean Anderson38f993a2008-06-26 23:15:51 -0300667{
sensoray-dev340a30c2014-02-12 17:25:45 -0300668 struct s2255_vc *vc = vb2_get_drv_priv(vq);
Dean Anderson9da62eb2014-02-05 14:58:06 -0300669 if (*nbuffers < S2255_MIN_BUFS)
670 *nbuffers = S2255_MIN_BUFS;
sensoray-dev340a30c2014-02-12 17:25:45 -0300671 *nplanes = 1;
672 sizes[0] = vc->width * vc->height * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300673 return 0;
674}
675
sensoray-dev340a30c2014-02-12 17:25:45 -0300676static int buffer_prepare(struct vb2_buffer *vb)
Dean Anderson38f993a2008-06-26 23:15:51 -0300677{
sensoray-dev340a30c2014-02-12 17:25:45 -0300678 struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300679 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300680 int w = vc->width;
681 int h = vc->height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300682 unsigned long size;
683
684 dprintk(vc->dev, 4, "%s\n", __func__);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300685 if (vc->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300686 return -EINVAL;
687
Dean Anderson5e950fa2014-02-04 18:16:24 -0300688 if ((w < norm_minw(vc)) ||
689 (w > norm_maxw(vc)) ||
690 (h < norm_minh(vc)) ||
691 (h > norm_maxh(vc))) {
Dean Anderson92cde472014-02-05 17:38:42 -0300692 dprintk(vc->dev, 4, "invalid buffer prepare\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300693 return -EINVAL;
694 }
sensoray-dev340a30c2014-02-12 17:25:45 -0300695 size = w * h * (vc->fmt->depth >> 3);
696 if (vb2_plane_size(vb, 0) < size) {
Dean Anderson92cde472014-02-05 17:38:42 -0300697 dprintk(vc->dev, 4, "invalid buffer prepare\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300698 return -EINVAL;
699 }
700
sensoray-dev340a30c2014-02-12 17:25:45 -0300701 vb2_set_plane_payload(&buf->vb, 0, size);
Dean Anderson38f993a2008-06-26 23:15:51 -0300702 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300703}
704
sensoray-dev340a30c2014-02-12 17:25:45 -0300705static void buffer_queue(struct vb2_buffer *vb)
Dean Anderson38f993a2008-06-26 23:15:51 -0300706{
707 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
sensoray-dev340a30c2014-02-12 17:25:45 -0300708 struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
709 unsigned long flags = 0;
Dean Anderson92cde472014-02-05 17:38:42 -0300710 dprintk(vc->dev, 1, "%s\n", __func__);
sensoray-dev340a30c2014-02-12 17:25:45 -0300711 spin_lock_irqsave(&vc->qlock, flags);
712 list_add_tail(&buf->list, &vc->buf_list);
713 spin_unlock_irqrestore(&vc->qlock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300714}
715
sensoray-dev340a30c2014-02-12 17:25:45 -0300716static int start_streaming(struct vb2_queue *vq, unsigned int count);
Hans Verkuile37559b2014-04-17 02:47:21 -0300717static void stop_streaming(struct vb2_queue *vq);
Dean Anderson38f993a2008-06-26 23:15:51 -0300718
sensoray-dev340a30c2014-02-12 17:25:45 -0300719static struct vb2_ops s2255_video_qops = {
720 .queue_setup = queue_setup,
Dean Anderson38f993a2008-06-26 23:15:51 -0300721 .buf_prepare = buffer_prepare,
722 .buf_queue = buffer_queue,
sensoray-dev340a30c2014-02-12 17:25:45 -0300723 .start_streaming = start_streaming,
724 .stop_streaming = stop_streaming,
725 .wait_prepare = vb2_ops_wait_prepare,
726 .wait_finish = vb2_ops_wait_finish,
Dean Anderson38f993a2008-06-26 23:15:51 -0300727};
728
Dean Anderson38f993a2008-06-26 23:15:51 -0300729static int vidioc_querycap(struct file *file, void *priv,
730 struct v4l2_capability *cap)
731{
sensoray-dev340a30c2014-02-12 17:25:45 -0300732 struct s2255_vc *vc = video_drvdata(file);
733 struct s2255_dev *dev = vc->dev;
Hans Verkuil39696002013-02-07 07:06:21 -0300734
Dean Anderson38f993a2008-06-26 23:15:51 -0300735 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
736 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300737 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
sensoray-dev340a30c2014-02-12 17:25:45 -0300738 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
739 V4L2_CAP_READWRITE;
Hans Verkuil39696002013-02-07 07:06:21 -0300740 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300741 return 0;
742}
743
744static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
745 struct v4l2_fmtdesc *f)
746{
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300747 int index = f->index;
Dean Anderson38f993a2008-06-26 23:15:51 -0300748
749 if (index >= ARRAY_SIZE(formats))
750 return -EINVAL;
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300751 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
752 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
753 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300754 strlcpy(f->description, formats[index].name, sizeof(f->description));
755 f->pixelformat = formats[index].fourcc;
756 return 0;
757}
758
759static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
760 struct v4l2_format *f)
761{
sensoray-dev340a30c2014-02-12 17:25:45 -0300762 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300763 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300764
Dean Anderson5e950fa2014-02-04 18:16:24 -0300765 f->fmt.pix.width = vc->width;
766 f->fmt.pix.height = vc->height;
Hans Verkuil92513612013-02-15 06:05:08 -0300767 if (f->fmt.pix.height >=
768 (is_ntsc ? NUM_LINES_1CIFS_NTSC : NUM_LINES_1CIFS_PAL) * 2)
769 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
770 else
771 f->fmt.pix.field = V4L2_FIELD_TOP;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300772 f->fmt.pix.pixelformat = vc->fmt->fourcc;
773 f->fmt.pix.bytesperline = f->fmt.pix.width * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300774 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300775 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
776 f->fmt.pix.priv = 0;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300777 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300778}
779
780static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
781 struct v4l2_format *f)
782{
783 const struct s2255_fmt *fmt;
784 enum v4l2_field field;
sensoray-dev340a30c2014-02-12 17:25:45 -0300785 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300786 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300787
788 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
789
790 if (fmt == NULL)
791 return -EINVAL;
792
793 field = f->fmt.pix.field;
Dean Anderson38f993a2008-06-26 23:15:51 -0300794
Dean Anderson92cde472014-02-05 17:38:42 -0300795 dprintk(vc->dev, 50, "%s NTSC: %d suggested width: %d, height: %d\n",
Dean Anderson85b85482010-04-08 23:51:17 -0300796 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300797 if (is_ntsc) {
798 /* NTSC */
799 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
800 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300801 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300802 } else {
803 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
Hans Verkuil92513612013-02-15 06:05:08 -0300804 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300805 }
806 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
807 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
808 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
809 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
810 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
811 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
812 else
813 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
814 } else {
815 /* PAL */
816 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
817 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300818 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300819 } else {
820 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300821 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300822 }
Hans Verkuil92513612013-02-15 06:05:08 -0300823 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300824 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300825 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300826 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300827 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300828 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300829 else
Dean Anderson38f993a2008-06-26 23:15:51 -0300830 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300831 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300832 f->fmt.pix.field = field;
833 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
834 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300835 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
836 f->fmt.pix.priv = 0;
Dean Anderson92cde472014-02-05 17:38:42 -0300837 dprintk(vc->dev, 50, "%s: set width %d height %d field %d\n", __func__,
Dean Anderson85b85482010-04-08 23:51:17 -0300838 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300839 return 0;
840}
841
842static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
843 struct v4l2_format *f)
844{
sensoray-dev340a30c2014-02-12 17:25:45 -0300845 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson38f993a2008-06-26 23:15:51 -0300846 const struct s2255_fmt *fmt;
sensoray-dev340a30c2014-02-12 17:25:45 -0300847 struct vb2_queue *q = &vc->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300848 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300849 int ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300850
sensoray-dev340a30c2014-02-12 17:25:45 -0300851 ret = vidioc_try_fmt_vid_cap(file, vc, f);
Dean Anderson38f993a2008-06-26 23:15:51 -0300852
853 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300854 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300855
856 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
857
858 if (fmt == NULL)
859 return -EINVAL;
860
sensoray-dev340a30c2014-02-12 17:25:45 -0300861 if (vb2_is_busy(q)) {
Dean Anderson92cde472014-02-05 17:38:42 -0300862 dprintk(vc->dev, 1, "queue busy\n");
sensoray-dev340a30c2014-02-12 17:25:45 -0300863 return -EBUSY;
Dean Anderson38f993a2008-06-26 23:15:51 -0300864 }
865
Dean Anderson5e950fa2014-02-04 18:16:24 -0300866 mode = vc->mode;
867 vc->fmt = fmt;
868 vc->width = f->fmt.pix.width;
869 vc->height = f->fmt.pix.height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300870 vc->field = f->fmt.pix.field;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300871 if (vc->width > norm_minw(vc)) {
872 if (vc->height > norm_minh(vc)) {
873 if (vc->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -0300874 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300875 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -0300876 else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300877 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -0300878 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300879 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300880
881 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300882 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300883 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300884 /* color mode */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300885 switch (vc->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300886 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300887 mode.color &= ~MASK_COLOR;
888 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -0300889 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300890 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300891 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300892 mode.color &= ~MASK_COLOR;
893 mode.color |= COLOR_JPG;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300894 mode.color |= (vc->jpegqual << 8);
Dean Anderson14d96262008-08-25 13:58:55 -0300895 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300896 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300897 mode.color &= ~MASK_COLOR;
898 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300899 break;
900 case V4L2_PIX_FMT_YUYV:
901 case V4L2_PIX_FMT_UYVY:
902 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300903 mode.color &= ~MASK_COLOR;
904 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -0300905 break;
906 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300907 if ((mode.color & MASK_COLOR) != (vc->mode.color & MASK_COLOR))
Dean Andersonfe85ce92010-06-01 19:12:07 -0300908 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300909 else if (mode.scale != vc->mode.scale)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300910 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300911 else if (mode.format != vc->mode.format)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300912 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300913 vc->mode = mode;
914 (void) s2255_set_mode(vc, &mode);
sensoray-dev340a30c2014-02-12 17:25:45 -0300915 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300916}
917
Dean Anderson38f993a2008-06-26 23:15:51 -0300918
Dean Anderson38f993a2008-06-26 23:15:51 -0300919/* write to the configuration pipe, synchronously */
920static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
921 int size)
922{
923 int pipe;
924 int done;
925 long retval = -1;
926 if (udev) {
927 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
928 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
929 }
930 return retval;
931}
932
933static u32 get_transfer_size(struct s2255_mode *mode)
934{
935 int linesPerFrame = LINE_SZ_DEF;
936 int pixelsPerLine = NUM_LINES_DEF;
937 u32 outImageSize;
938 u32 usbInSize;
939 unsigned int mask_mult;
940
941 if (mode == NULL)
942 return 0;
943
944 if (mode->format == FORMAT_NTSC) {
945 switch (mode->scale) {
946 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -0300947 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -0300948 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
949 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
950 break;
951 case SCALE_2CIFS:
952 linesPerFrame = NUM_LINES_2CIFS_NTSC;
953 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
954 break;
955 case SCALE_1CIFS:
956 linesPerFrame = NUM_LINES_1CIFS_NTSC;
957 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
958 break;
959 default:
960 break;
961 }
962 } else if (mode->format == FORMAT_PAL) {
963 switch (mode->scale) {
964 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -0300965 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -0300966 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
967 pixelsPerLine = LINE_SZ_4CIFS_PAL;
968 break;
969 case SCALE_2CIFS:
970 linesPerFrame = NUM_LINES_2CIFS_PAL;
971 pixelsPerLine = LINE_SZ_2CIFS_PAL;
972 break;
973 case SCALE_1CIFS:
974 linesPerFrame = NUM_LINES_1CIFS_PAL;
975 pixelsPerLine = LINE_SZ_1CIFS_PAL;
976 break;
977 default:
978 break;
979 }
980 }
981 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -0300982 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300983 /* 2 bytes/pixel if not monochrome */
984 outImageSize *= 2;
985 }
986
987 /* total bytes to send including prefix and 4K padding;
988 must be a multiple of USB_READ_SIZE */
989 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
990 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
991 /* if size not a multiple of USB_READ_SIZE */
992 if (usbInSize & ~mask_mult)
993 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
994 return usbInSize;
995}
996
Dean Anderson85b85482010-04-08 23:51:17 -0300997static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -0300998{
999 struct device *dev = &sdev->udev->dev;
1000 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001001 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1002 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001003 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001004 dev_info(dev, "------------------------------------------------\n");
1005}
1006
1007/*
1008 * set mode is the function which controls the DSP.
1009 * the restart parameter in struct s2255_mode should be set whenever
1010 * the image size could change via color format, video system or image
1011 * size.
1012 * When the restart parameter is set, we sleep for ONE frame to allow the
1013 * DSP time to get the new frame
1014 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001015static int s2255_set_mode(struct s2255_vc *vc,
Dean Anderson38f993a2008-06-26 23:15:51 -03001016 struct s2255_mode *mode)
1017{
1018 int res;
Dean Anderson38f993a2008-06-26 23:15:51 -03001019 unsigned long chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001020 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001021 int i;
Dean Anderson47d8c882014-02-05 15:43:51 -03001022 __le32 *buffer = dev->cmdbuf;
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001023
Dean Anderson47d8c882014-02-05 15:43:51 -03001024 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001025 chn_rev = G_chnmap[vc->idx];
1026 dprintk(dev, 3, "%s channel: %d\n", __func__, vc->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001027 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001028 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1029 mode->color &= ~MASK_COLOR;
1030 mode->color |= COLOR_JPG;
1031 mode->color &= ~MASK_JPG_QUALITY;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001032 mode->color |= (vc->jpegqual << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001033 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001034 /* save the mode */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001035 vc->mode = *mode;
1036 vc->req_image_size = get_transfer_size(mode);
1037 dprintk(dev, 1, "%s: reqsize %ld\n", __func__, vc->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001038 /* set the mode */
1039 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001040 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001041 buffer[2] = CMD_SET_MODE;
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001042 for (i = 0; i < sizeof(struct s2255_mode) / sizeof(u32); i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001043 buffer[3 + i] = cpu_to_le32(((u32 *)&vc->mode)[i]);
1044 vc->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001045 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1046 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001047 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001048 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001049 if (mode->restart) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001050 wait_event_timeout(vc->wait_setmode,
1051 (vc->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001052 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001053 if (vc->setmode_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001054 dprintk(dev, 0, "s2255: no set mode response\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001055 res = -EFAULT;
1056 }
1057 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001058 /* clear the restart flag */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001059 vc->mode.restart = 0;
1060 dprintk(dev, 1, "%s chn %d, result: %d\n", __func__, vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03001061 mutex_unlock(&dev->cmdlock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001062 return res;
1063}
1064
Dean Anderson5e950fa2014-02-04 18:16:24 -03001065static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001066{
1067 int res;
Dean Anderson4de39f52010-03-03 19:39:19 -03001068 u32 chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001069 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03001070 __le32 *buffer = dev->cmdbuf;
1071
1072 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001073 chn_rev = G_chnmap[vc->idx];
1074 dprintk(dev, 4, "%s chan %d\n", __func__, vc->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001075 /* form the get vid status command */
1076 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001077 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001078 buffer[2] = CMD_STATUS;
1079 *pstatus = 0;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001080 vc->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001081 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001082 wait_event_timeout(vc->wait_vidstatus,
1083 (vc->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001084 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001085 if (vc->vidstatus_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001086 dprintk(dev, 0, "s2255: no vidstatus response\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001087 res = -EFAULT;
1088 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001089 *pstatus = vc->vidstatus;
sensoray-devf5402002014-01-29 15:24:07 -03001090 dprintk(dev, 4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson47d8c882014-02-05 15:43:51 -03001091 mutex_unlock(&dev->cmdlock);
Dean Anderson4de39f52010-03-03 19:39:19 -03001092 return res;
1093}
1094
sensoray-dev340a30c2014-02-12 17:25:45 -03001095static int start_streaming(struct vb2_queue *vq, unsigned int count)
Dean Anderson38f993a2008-06-26 23:15:51 -03001096{
sensoray-dev340a30c2014-02-12 17:25:45 -03001097 struct s2255_vc *vc = vb2_get_drv_priv(vq);
Dean Anderson38f993a2008-06-26 23:15:51 -03001098 int j;
Dean Anderson92cde472014-02-05 17:38:42 -03001099
Dean Anderson5e950fa2014-02-04 18:16:24 -03001100 vc->last_frame = -1;
1101 vc->bad_payload = 0;
1102 vc->cur_frame = 0;
1103 vc->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001104 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001105 vc->buffer.frame[j].ulState = S2255_READ_IDLE;
1106 vc->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001107 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001108 return s2255_start_acquire(vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03001109}
1110
sensoray-dev340a30c2014-02-12 17:25:45 -03001111/* abort streaming and wait for last buffer */
Hans Verkuile37559b2014-04-17 02:47:21 -03001112static void stop_streaming(struct vb2_queue *vq)
Dean Anderson38f993a2008-06-26 23:15:51 -03001113{
sensoray-dev340a30c2014-02-12 17:25:45 -03001114 struct s2255_vc *vc = vb2_get_drv_priv(vq);
1115 struct s2255_buffer *buf, *node;
1116 unsigned long flags;
1117 (void) s2255_stop_acquire(vc);
1118 spin_lock_irqsave(&vc->qlock, flags);
1119 list_for_each_entry_safe(buf, node, &vc->buf_list, list) {
1120 list_del(&buf->list);
1121 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
1122 dprintk(vc->dev, 2, "[%p/%d] done\n",
1123 buf, buf->vb.v4l2_buf.index);
1124 }
1125 spin_unlock_irqrestore(&vc->qlock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -03001126}
1127
Hans Verkuil314527a2013-03-15 06:10:40 -03001128static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i)
Dean Anderson38f993a2008-06-26 23:15:51 -03001129{
sensoray-dev340a30c2014-02-12 17:25:45 -03001130 struct s2255_vc *vc = video_drvdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001131 struct s2255_mode mode;
sensoray-dev340a30c2014-02-12 17:25:45 -03001132 struct vb2_queue *q = &vc->vb_vidq;
Hans Verkuil469af772013-02-15 06:12:58 -03001133
sensoray-dev340a30c2014-02-12 17:25:45 -03001134 /*
1135 * Changing the standard implies a format change, which is not allowed
1136 * while buffers for use with streaming have already been allocated.
1137 */
1138 if (vb2_is_busy(q))
1139 return -EBUSY;
1140
Dean Anderson92cde472014-02-05 17:38:42 -03001141 mode = vc->mode;
Hans Verkuil314527a2013-03-15 06:10:40 -03001142 if (i & V4L2_STD_525_60) {
Dean Anderson92cde472014-02-05 17:38:42 -03001143 dprintk(vc->dev, 4, "%s 60 Hz\n", __func__);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001144 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001145 if (mode.format != FORMAT_NTSC) {
1146 mode.restart = 1;
1147 mode.format = FORMAT_NTSC;
1148 mode.fdec = FDEC_1;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001149 vc->width = LINE_SZ_4CIFS_NTSC;
1150 vc->height = NUM_LINES_4CIFS_NTSC * 2;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001151 }
Hans Verkuil314527a2013-03-15 06:10:40 -03001152 } else if (i & V4L2_STD_625_50) {
Dean Anderson92cde472014-02-05 17:38:42 -03001153 dprintk(vc->dev, 4, "%s 50 Hz\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001154 if (mode.format != FORMAT_PAL) {
1155 mode.restart = 1;
1156 mode.format = FORMAT_PAL;
1157 mode.fdec = FDEC_1;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001158 vc->width = LINE_SZ_4CIFS_PAL;
1159 vc->height = NUM_LINES_4CIFS_PAL * 2;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001160 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001161 } else
1162 return -EINVAL;
Dean Anderson92cde472014-02-05 17:38:42 -03001163 vc->std = i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001164 if (mode.restart)
Dean Anderson92cde472014-02-05 17:38:42 -03001165 s2255_set_mode(vc, &mode);
sensoray-dev340a30c2014-02-12 17:25:45 -03001166 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001167}
1168
Hans Verkuil469af772013-02-15 06:12:58 -03001169static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *i)
1170{
sensoray-dev340a30c2014-02-12 17:25:45 -03001171 struct s2255_vc *vc = video_drvdata(file);
Hans Verkuil469af772013-02-15 06:12:58 -03001172
Dean Anderson92cde472014-02-05 17:38:42 -03001173 *i = vc->std;
Hans Verkuil469af772013-02-15 06:12:58 -03001174 return 0;
1175}
1176
Dean Anderson38f993a2008-06-26 23:15:51 -03001177/* Sensoray 2255 is a multiple channel capture device.
1178 It does not have a "crossbar" of inputs.
1179 We use one V4L device per channel. The user must
1180 be aware that certain combinations are not allowed.
1181 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1182 at once in color(you can do full fps on 4 channels with greyscale.
1183*/
1184static int vidioc_enum_input(struct file *file, void *priv,
1185 struct v4l2_input *inp)
1186{
sensoray-dev340a30c2014-02-12 17:25:45 -03001187 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson92cde472014-02-05 17:38:42 -03001188 struct s2255_dev *dev = vc->dev;
Dean Anderson4de39f52010-03-03 19:39:19 -03001189 u32 status = 0;
Dean Anderson92cde472014-02-05 17:38:42 -03001190
Dean Anderson38f993a2008-06-26 23:15:51 -03001191 if (inp->index != 0)
1192 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001193 inp->type = V4L2_INPUT_TYPE_CAMERA;
1194 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001195 inp->status = 0;
1196 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1197 int rc;
Dean Anderson92cde472014-02-05 17:38:42 -03001198 rc = s2255_cmd_status(vc, &status);
sensoray-devf5402002014-01-29 15:24:07 -03001199 dprintk(dev, 4, "s2255_cmd_status rc: %d status %x\n",
1200 rc, status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001201 if (rc == 0)
1202 inp->status = (status & 0x01) ? 0
1203 : V4L2_IN_ST_NO_SIGNAL;
1204 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001205 switch (dev->pid) {
1206 case 0x2255:
1207 default:
1208 strlcpy(inp->name, "Composite", sizeof(inp->name));
1209 break;
1210 case 0x2257:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001211 strlcpy(inp->name, (vc->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001212 sizeof(inp->name));
1213 break;
1214 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001215 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001216}
1217
1218static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1219{
1220 *i = 0;
1221 return 0;
1222}
1223static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1224{
1225 if (i > 0)
1226 return -EINVAL;
1227 return 0;
1228}
1229
Hans Verkuil192f1e72013-02-15 05:51:21 -03001230static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
Dean Anderson38f993a2008-06-26 23:15:51 -03001231{
Dean Anderson5e950fa2014-02-04 18:16:24 -03001232 struct s2255_vc *vc =
1233 container_of(ctrl->handler, struct s2255_vc, hdl);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001234 struct s2255_mode mode;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001235 mode = vc->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001236 /* update the mode to the corresponding value */
1237 switch (ctrl->id) {
1238 case V4L2_CID_BRIGHTNESS:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001239 mode.bright = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001240 break;
1241 case V4L2_CID_CONTRAST:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001242 mode.contrast = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001243 break;
1244 case V4L2_CID_HUE:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001245 mode.hue = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001246 break;
1247 case V4L2_CID_SATURATION:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001248 mode.saturation = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001249 break;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001250 case V4L2_CID_S2255_COLORFILTER:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001251 mode.color &= ~MASK_INPUT_TYPE;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001252 mode.color |= !ctrl->val << 16;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001253 break;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001254 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001255 vc->jpegqual = ctrl->val;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001256 return 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001257 default:
1258 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001259 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001260 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001261 /* set mode here. Note: stream does not need restarted.
1262 some V4L programs restart stream unnecessarily
1263 after a s_crtl.
1264 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001265 s2255_set_mode(vc, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001266 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001267}
1268
Dean Anderson22b88d42008-08-29 15:33:19 -03001269static int vidioc_g_jpegcomp(struct file *file, void *priv,
1270 struct v4l2_jpegcompression *jc)
1271{
sensoray-dev340a30c2014-02-12 17:25:45 -03001272 struct s2255_vc *vc = video_drvdata(file);
Hans Verkuil7041dec2013-02-15 05:53:45 -03001273
1274 memset(jc, 0, sizeof(*jc));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001275 jc->quality = vc->jpegqual;
Dean Anderson92cde472014-02-05 17:38:42 -03001276 dprintk(vc->dev, 2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001277 return 0;
1278}
1279
1280static int vidioc_s_jpegcomp(struct file *file, void *priv,
Hans Verkuild88aab52012-09-17 05:05:25 -03001281 const struct v4l2_jpegcompression *jc)
Dean Anderson22b88d42008-08-29 15:33:19 -03001282{
sensoray-dev340a30c2014-02-12 17:25:45 -03001283 struct s2255_vc *vc = video_drvdata(file);
1284
Dean Anderson22b88d42008-08-29 15:33:19 -03001285 if (jc->quality < 0 || jc->quality > 100)
1286 return -EINVAL;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001287 v4l2_ctrl_s_ctrl(vc->jpegqual_ctrl, jc->quality);
Dean Anderson92cde472014-02-05 17:38:42 -03001288 dprintk(vc->dev, 2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001289 return 0;
1290}
Dean Anderson7d853532009-05-15 14:32:04 -03001291
1292static int vidioc_g_parm(struct file *file, void *priv,
1293 struct v4l2_streamparm *sp)
1294{
Dean Andersone6b44bc2010-03-08 20:04:48 -03001295 __u32 def_num, def_dem;
sensoray-dev340a30c2014-02-12 17:25:45 -03001296 struct s2255_vc *vc = video_drvdata(file);
1297
Dean Anderson7d853532009-05-15 14:32:04 -03001298 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1299 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001300 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001301 sp->parm.capture.capturemode = vc->cap_parm.capturemode;
sensoray-dev340a30c2014-02-12 17:25:45 -03001302 sp->parm.capture.readbuffers = S2255_MIN_BUFS;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001303 def_num = (vc->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1304 def_dem = (vc->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001305 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001306 switch (vc->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001307 default:
1308 case FDEC_1:
1309 sp->parm.capture.timeperframe.numerator = def_num;
1310 break;
1311 case FDEC_2:
1312 sp->parm.capture.timeperframe.numerator = def_num * 2;
1313 break;
1314 case FDEC_3:
1315 sp->parm.capture.timeperframe.numerator = def_num * 3;
1316 break;
1317 case FDEC_5:
1318 sp->parm.capture.timeperframe.numerator = def_num * 5;
1319 break;
1320 }
Dean Anderson92cde472014-02-05 17:38:42 -03001321 dprintk(vc->dev, 4, "%s capture mode, %d timeperframe %d/%d\n",
sensoray-devf5402002014-01-29 15:24:07 -03001322 __func__,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001323 sp->parm.capture.capturemode,
1324 sp->parm.capture.timeperframe.numerator,
1325 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001326 return 0;
1327}
1328
1329static int vidioc_s_parm(struct file *file, void *priv,
1330 struct v4l2_streamparm *sp)
1331{
sensoray-dev340a30c2014-02-12 17:25:45 -03001332 struct s2255_vc *vc = video_drvdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001333 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001334 int fdec = FDEC_1;
1335 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001336 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1337 return -EINVAL;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001338 mode = vc->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001339 /* high quality capture mode requires a stream restart */
sensoray-dev340a30c2014-02-12 17:25:45 -03001340 if ((vc->cap_parm.capturemode != sp->parm.capture.capturemode)
1341 && vb2_is_streaming(&vc->vb_vidq))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001342 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001343 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1344 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001345 if (def_dem != sp->parm.capture.timeperframe.denominator)
1346 sp->parm.capture.timeperframe.numerator = def_num;
1347 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1348 sp->parm.capture.timeperframe.numerator = def_num;
1349 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1350 sp->parm.capture.timeperframe.numerator = def_num * 2;
1351 fdec = FDEC_2;
1352 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1353 sp->parm.capture.timeperframe.numerator = def_num * 3;
1354 fdec = FDEC_3;
1355 } else {
1356 sp->parm.capture.timeperframe.numerator = def_num * 5;
1357 fdec = FDEC_5;
1358 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001359 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001360 sp->parm.capture.timeperframe.denominator = def_dem;
sensoray-dev340a30c2014-02-12 17:25:45 -03001361 sp->parm.capture.readbuffers = S2255_MIN_BUFS;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001362 s2255_set_mode(vc, &mode);
Dean Anderson92cde472014-02-05 17:38:42 -03001363 dprintk(vc->dev, 4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
Dean Andersone6b44bc2010-03-08 20:04:48 -03001364 __func__,
1365 sp->parm.capture.capturemode,
1366 sp->parm.capture.timeperframe.numerator,
1367 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001368 return 0;
1369}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001370
Hans Verkuil05e5d442013-02-15 06:09:18 -03001371#define NUM_SIZE_ENUMS 3
1372static const struct v4l2_frmsize_discrete ntsc_sizes[] = {
1373 { 640, 480 },
1374 { 640, 240 },
1375 { 320, 240 },
1376};
1377static const struct v4l2_frmsize_discrete pal_sizes[] = {
1378 { 704, 576 },
1379 { 704, 288 },
1380 { 352, 288 },
1381};
1382
1383static int vidioc_enum_framesizes(struct file *file, void *priv,
1384 struct v4l2_frmsizeenum *fe)
1385{
sensoray-dev340a30c2014-02-12 17:25:45 -03001386 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001387 int is_ntsc = vc->std & V4L2_STD_525_60;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001388 const struct s2255_fmt *fmt;
1389
1390 if (fe->index >= NUM_SIZE_ENUMS)
1391 return -EINVAL;
1392
1393 fmt = format_by_fourcc(fe->pixel_format);
1394 if (fmt == NULL)
1395 return -EINVAL;
1396 fe->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1397 fe->discrete = is_ntsc ? ntsc_sizes[fe->index] : pal_sizes[fe->index];
1398 return 0;
1399}
1400
Dean Andersone6b44bc2010-03-08 20:04:48 -03001401static int vidioc_enum_frameintervals(struct file *file, void *priv,
1402 struct v4l2_frmivalenum *fe)
1403{
sensoray-dev340a30c2014-02-12 17:25:45 -03001404 struct s2255_vc *vc = video_drvdata(file);
Hans Verkuil05e5d442013-02-15 06:09:18 -03001405 const struct s2255_fmt *fmt;
1406 const struct v4l2_frmsize_discrete *sizes;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001407 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001408#define NUM_FRAME_ENUMS 4
1409 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
Hans Verkuil05e5d442013-02-15 06:09:18 -03001410 int i;
1411
Mauro Carvalho Chehab199ab8f2012-10-27 16:29:34 -03001412 if (fe->index >= NUM_FRAME_ENUMS)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001413 return -EINVAL;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001414
1415 fmt = format_by_fourcc(fe->pixel_format);
1416 if (fmt == NULL)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001417 return -EINVAL;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001418
1419 sizes = is_ntsc ? ntsc_sizes : pal_sizes;
1420 for (i = 0; i < NUM_SIZE_ENUMS; i++, sizes++)
1421 if (fe->width == sizes->width &&
1422 fe->height == sizes->height)
1423 break;
1424 if (i == NUM_SIZE_ENUMS)
1425 return -EINVAL;
1426
Dean Andersone6b44bc2010-03-08 20:04:48 -03001427 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1428 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1429 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
Dean Anderson92cde472014-02-05 17:38:42 -03001430 dprintk(vc->dev, 4, "%s discrete %d/%d\n", __func__,
sensoray-devf5402002014-01-29 15:24:07 -03001431 fe->discrete.numerator,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001432 fe->discrete.denominator);
1433 return 0;
1434}
1435
sensoray-dev340a30c2014-02-12 17:25:45 -03001436static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001437{
Dean Anderson5e950fa2014-02-04 18:16:24 -03001438 struct s2255_vc *vc = video_drvdata(file);
sensoray-dev340a30c2014-02-12 17:25:45 -03001439 struct s2255_dev *dev = vc->dev;
Dean Anderson14d96262008-08-25 13:58:55 -03001440 int state;
sensoray-dev340a30c2014-02-12 17:25:45 -03001441 int rc = 0;
1442
1443 rc = v4l2_fh_open(file);
1444 if (rc != 0)
1445 return rc;
1446
1447 dprintk(dev, 1, "s2255: %s\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001448 state = atomic_read(&dev->fw_data->fw_state);
1449 switch (state) {
1450 case S2255_FW_DISCONNECTING:
Dean Andersonff7e22d2010-04-08 23:38:07 -03001451 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001452 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001453 s2255_dev_err(&dev->udev->dev,
1454 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001455 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001456 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001457 ((atomic_read(&dev->fw_data->fw_state)
1458 == S2255_FW_SUCCESS) ||
1459 (atomic_read(&dev->fw_data->fw_state)
1460 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001461 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001462 /* state may have changed, re-read */
1463 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001464 break;
1465 case S2255_FW_NOTLOADED:
1466 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001467 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1468 driver loaded and then device immediately opened */
sensoray-devf5402002014-01-29 15:24:07 -03001469 pr_info("%s waiting for firmware load\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001470 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001471 ((atomic_read(&dev->fw_data->fw_state)
1472 == S2255_FW_SUCCESS) ||
1473 (atomic_read(&dev->fw_data->fw_state)
1474 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001475 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001476 /* state may have changed, re-read */
1477 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001478 break;
1479 case S2255_FW_SUCCESS:
1480 default:
1481 break;
1482 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001483 /* state may have changed in above switch statement */
1484 switch (state) {
1485 case S2255_FW_SUCCESS:
1486 break;
1487 case S2255_FW_FAILED:
sensoray-devf5402002014-01-29 15:24:07 -03001488 pr_info("2255 firmware load failed.\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03001489 return -ENODEV;
1490 case S2255_FW_DISCONNECTING:
sensoray-devf5402002014-01-29 15:24:07 -03001491 pr_info("%s: disconnecting\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001492 return -ENODEV;
1493 case S2255_FW_LOADED_DSPWAIT:
1494 case S2255_FW_NOTLOADED:
sensoray-devf5402002014-01-29 15:24:07 -03001495 pr_info("%s: firmware not loaded, please retry\n",
1496 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001497 /*
1498 * Timeout on firmware load means device unusable.
1499 * Set firmware failure state.
1500 * On next s2255_open the firmware will be reloaded.
1501 */
1502 atomic_set(&dev->fw_data->fw_state,
1503 S2255_FW_FAILED);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001504 return -EAGAIN;
1505 default:
sensoray-devf5402002014-01-29 15:24:07 -03001506 pr_info("%s: unknown state\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001507 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001508 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001509 if (!vc->configured) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001510 /* configure channel to default state */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001511 vc->fmt = &formats[0];
1512 s2255_set_mode(vc, &vc->mode);
1513 vc->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001514 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001515 return 0;
1516}
1517
Dean Andersond62e85a2010-04-09 19:54:26 -03001518static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001519{
sensoray-devf5402002014-01-29 15:24:07 -03001520 dprintk(dev, 1, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001521 /* board shutdown stops the read pipe if it is running */
1522 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001523 /* make sure firmware still not trying to load */
Kirill Tkhai9f6be2b2014-04-17 17:47:04 -03001524 del_timer_sync(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001525 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001526 usb_kill_urb(dev->fw_data->fw_urb);
1527 usb_free_urb(dev->fw_data->fw_urb);
1528 dev->fw_data->fw_urb = NULL;
1529 }
Jesper Juhl3fc82fa2012-04-09 16:50:04 -03001530 release_firmware(dev->fw_data->fw);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001531 kfree(dev->fw_data->pfw_data);
1532 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001533 /* reset the DSP so firmware can be reloaded next time */
1534 s2255_reset_dsppower(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001535 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001536 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001537 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03001538 kfree(dev->cmdbuf);
Dean Andersonb7732a32009-03-30 11:59:56 -03001539 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001540}
1541
Hans Verkuilbec43662008-12-30 06:58:20 -03001542static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001543 .owner = THIS_MODULE,
1544 .open = s2255_open,
sensoray-dev340a30c2014-02-12 17:25:45 -03001545 .release = vb2_fop_release,
1546 .poll = vb2_fop_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001547 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
sensoray-dev340a30c2014-02-12 17:25:45 -03001548 .mmap = vb2_fop_mmap,
1549 .read = vb2_fop_read,
Dean Anderson38f993a2008-06-26 23:15:51 -03001550};
1551
Hans Verkuila3998102008-07-21 02:57:38 -03001552static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001553 .vidioc_querycap = vidioc_querycap,
1554 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1555 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1556 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1557 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
sensoray-dev340a30c2014-02-12 17:25:45 -03001558 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1559 .vidioc_querybuf = vb2_ioctl_querybuf,
1560 .vidioc_qbuf = vb2_ioctl_qbuf,
1561 .vidioc_dqbuf = vb2_ioctl_dqbuf,
Dean Anderson38f993a2008-06-26 23:15:51 -03001562 .vidioc_s_std = vidioc_s_std,
Hans Verkuil469af772013-02-15 06:12:58 -03001563 .vidioc_g_std = vidioc_g_std,
Dean Anderson38f993a2008-06-26 23:15:51 -03001564 .vidioc_enum_input = vidioc_enum_input,
1565 .vidioc_g_input = vidioc_g_input,
1566 .vidioc_s_input = vidioc_s_input,
sensoray-dev340a30c2014-02-12 17:25:45 -03001567 .vidioc_streamon = vb2_ioctl_streamon,
1568 .vidioc_streamoff = vb2_ioctl_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001569 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1570 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001571 .vidioc_s_parm = vidioc_s_parm,
1572 .vidioc_g_parm = vidioc_g_parm,
Hans Verkuil05e5d442013-02-15 06:09:18 -03001573 .vidioc_enum_framesizes = vidioc_enum_framesizes,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001574 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuil44d06d82013-02-15 05:59:00 -03001575 .vidioc_log_status = v4l2_ctrl_log_status,
1576 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1577 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001578};
1579
Dean Andersonff7e22d2010-04-08 23:38:07 -03001580static void s2255_video_device_release(struct video_device *vdev)
1581{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001582 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001583 struct s2255_vc *vc =
1584 container_of(vdev, struct s2255_vc, vdev);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001585
sensoray-devf5402002014-01-29 15:24:07 -03001586 dprintk(dev, 4, "%s, chnls: %d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001587 atomic_read(&dev->num_channels));
Hans Verkuil192f1e72013-02-15 05:51:21 -03001588
Dean Anderson5e950fa2014-02-04 18:16:24 -03001589 v4l2_ctrl_handler_free(&vc->hdl);
sensoray-devf5402002014-01-29 15:24:07 -03001590
Dean Andersonfe85ce92010-06-01 19:12:07 -03001591 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001592 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001593 return;
1594}
1595
Hans Verkuila3998102008-07-21 02:57:38 -03001596static struct video_device template = {
1597 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001598 .fops = &s2255_fops_v4l,
1599 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001600 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001601 .tvnorms = S2255_NORMS,
Dean Anderson38f993a2008-06-26 23:15:51 -03001602};
1603
Hans Verkuil192f1e72013-02-15 05:51:21 -03001604static const struct v4l2_ctrl_ops s2255_ctrl_ops = {
1605 .s_ctrl = s2255_s_ctrl,
1606};
1607
1608static const struct v4l2_ctrl_config color_filter_ctrl = {
1609 .ops = &s2255_ctrl_ops,
1610 .name = "Color Filter",
1611 .id = V4L2_CID_S2255_COLORFILTER,
1612 .type = V4L2_CTRL_TYPE_BOOLEAN,
1613 .max = 1,
1614 .step = 1,
1615 .def = 1,
1616};
1617
Dean Anderson38f993a2008-06-26 23:15:51 -03001618static int s2255_probe_v4l(struct s2255_dev *dev)
1619{
1620 int ret;
1621 int i;
1622 int cur_nr = video_nr;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001623 struct s2255_vc *vc;
sensoray-dev340a30c2014-02-12 17:25:45 -03001624 struct vb2_queue *q;
1625
Dean Anderson65c6edb2010-04-20 17:21:32 -03001626 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1627 if (ret)
1628 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001629 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001630 /* register 4 video devices */
1631 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001632 vc = &dev->vc[i];
1633 INIT_LIST_HEAD(&vc->buf_list);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001634
Dean Anderson5e950fa2014-02-04 18:16:24 -03001635 v4l2_ctrl_handler_init(&vc->hdl, 6);
1636 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001637 V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001638 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001639 V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001640 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001641 V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001642 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001643 V4L2_CID_HUE, 0, 255, 1, DEF_HUE);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001644 vc->jpegqual_ctrl = v4l2_ctrl_new_std(&vc->hdl,
Hans Verkuil7041dec2013-02-15 05:53:45 -03001645 &s2255_ctrl_ops,
1646 V4L2_CID_JPEG_COMPRESSION_QUALITY,
1647 0, 100, 1, S2255_DEF_JPEG_QUAL);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001648 if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER &&
Dean Anderson5e950fa2014-02-04 18:16:24 -03001649 (dev->pid != 0x2257 || vc->idx <= 1))
1650 v4l2_ctrl_new_custom(&vc->hdl, &color_filter_ctrl,
sensoray-devf5402002014-01-29 15:24:07 -03001651 NULL);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001652 if (vc->hdl.error) {
1653 ret = vc->hdl.error;
1654 v4l2_ctrl_handler_free(&vc->hdl);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001655 dev_err(&dev->udev->dev, "couldn't register control\n");
1656 break;
1657 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001658 q = &vc->vb_vidq;
1659 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1660 q->io_modes = VB2_MMAP | VB2_READ | VB2_USERPTR;
1661 q->drv_priv = vc;
1662 q->lock = &vc->vb_lock;
1663 q->buf_struct_size = sizeof(struct s2255_buffer);
1664 q->mem_ops = &vb2_vmalloc_memops;
1665 q->ops = &s2255_video_qops;
Sakari Ailusade48682014-02-25 19:12:19 -03001666 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
sensoray-dev340a30c2014-02-12 17:25:45 -03001667 ret = vb2_queue_init(q);
1668 if (ret != 0) {
1669 dev_err(&dev->udev->dev,
1670 "%s vb2_queue_init 0x%x\n", __func__, ret);
1671 break;
1672 }
1673 /* register video devices */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001674 vc->vdev = template;
sensoray-dev340a30c2014-02-12 17:25:45 -03001675 vc->vdev.queue = q;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001676 vc->vdev.ctrl_handler = &vc->hdl;
1677 vc->vdev.lock = &dev->lock;
1678 vc->vdev.v4l2_dev = &dev->v4l2_dev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001679 video_set_drvdata(&vc->vdev, vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03001680 if (video_nr == -1)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001681 ret = video_register_device(&vc->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001682 VFL_TYPE_GRABBER,
1683 video_nr);
1684 else
Dean Anderson5e950fa2014-02-04 18:16:24 -03001685 ret = video_register_device(&vc->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001686 VFL_TYPE_GRABBER,
1687 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001688
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001689 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001690 dev_err(&dev->udev->dev,
1691 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001692 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001693 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001694 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001695 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Anderson5e950fa2014-02-04 18:16:24 -03001696 video_device_node_name(&vc->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001697
Dean Anderson38f993a2008-06-26 23:15:51 -03001698 }
sensoray-devf5402002014-01-29 15:24:07 -03001699 pr_info("Sensoray 2255 V4L driver Revision: %s\n",
1700 S2255_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001701 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001702 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001703 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001704 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001705 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001706 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
sensoray-devf5402002014-01-29 15:24:07 -03001707 pr_warn("s2255: Not all channels available.\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001708 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001709}
1710
Dean Anderson38f993a2008-06-26 23:15:51 -03001711/* this function moves the usb stream read pipe data
1712 * into the system buffers.
1713 * returns 0 on success, EAGAIN if more data to process( call this
1714 * function again).
1715 *
1716 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001717 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001718 * bytes 4-7: channel: 0-3
1719 * bytes 8-11: payload size: size of the frame
1720 * bytes 12-payloadsize+12: frame data
1721 */
1722static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1723{
Dean Anderson38f993a2008-06-26 23:15:51 -03001724 char *pdest;
1725 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001726 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001727 char *psrc;
1728 unsigned long copy_size;
1729 unsigned long size;
1730 s32 idx = -1;
1731 struct s2255_framei *frm;
1732 unsigned char *pdata;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001733 struct s2255_vc *vc;
sensoray-devf5402002014-01-29 15:24:07 -03001734 dprintk(dev, 100, "buffer to user\n");
Dean Anderson5e950fa2014-02-04 18:16:24 -03001735 vc = &dev->vc[dev->cc];
1736 idx = vc->cur_frame;
1737 frm = &vc->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001738 if (frm->ulState == S2255_READ_IDLE) {
1739 int jj;
1740 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03001741 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03001742 int payload;
1743 /* search for marker codes */
1744 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03001745 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03001746 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03001747 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03001748 case S2255_MARKER_FRAME:
sensoray-devf5402002014-01-29 15:24:07 -03001749 dprintk(dev, 4, "marker @ offset: %d [%x %x]\n",
1750 jj, pdata[0], pdata[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001751 offset = jj + PREFIX_SIZE;
1752 bframe = 1;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001753 cc = le32_to_cpu(pdword[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001754 if (cc >= MAX_CHANNELS) {
sensoray-devf5402002014-01-29 15:24:07 -03001755 dprintk(dev, 0,
1756 "bad channel\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001757 return -EINVAL;
1758 }
1759 /* reverse it */
1760 dev->cc = G_chnmap[cc];
Dean Anderson5e950fa2014-02-04 18:16:24 -03001761 vc = &dev->vc[dev->cc];
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001762 payload = le32_to_cpu(pdword[3]);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001763 if (payload > vc->req_image_size) {
1764 vc->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03001765 /* discard the bad frame */
1766 return -EINVAL;
1767 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001768 vc->pkt_size = payload;
1769 vc->jpg_size = le32_to_cpu(pdword[4]);
Dean Anderson14d96262008-08-25 13:58:55 -03001770 break;
1771 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001772
Dean Anderson14d96262008-08-25 13:58:55 -03001773 pdata += DEF_USB_BLOCK;
1774 jj += DEF_USB_BLOCK;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001775 if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001776 break;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001777 cc = G_chnmap[le32_to_cpu(pdword[1])];
Roel Kluinf14a2972009-10-23 07:59:42 -03001778 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001779 break;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001780 vc = &dev->vc[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03001781 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03001782 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03001783 /* check if channel valid */
1784 /* set mode ready */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001785 vc->setmode_ready = 1;
1786 wake_up(&vc->wait_setmode);
sensoray-devf5402002014-01-29 15:24:07 -03001787 dprintk(dev, 5, "setmode rdy %d\n", cc);
Dean Anderson14d96262008-08-25 13:58:55 -03001788 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03001789 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03001790 dev->chn_ready |= (1 << cc);
1791 if ((dev->chn_ready & 0x0f) != 0x0f)
1792 break;
1793 /* all channels ready */
sensoray-devf5402002014-01-29 15:24:07 -03001794 pr_info("s2255: fw loaded\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001795 atomic_set(&dev->fw_data->fw_state,
1796 S2255_FW_SUCCESS);
1797 wake_up(&dev->fw_data->wait_fw);
1798 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03001799 case S2255_RESPONSE_STATUS:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001800 vc->vidstatus = le32_to_cpu(pdword[3]);
1801 vc->vidstatus_ready = 1;
1802 wake_up(&vc->wait_vidstatus);
sensoray-devf5402002014-01-29 15:24:07 -03001803 dprintk(dev, 5, "vstat %x chan %d\n",
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001804 le32_to_cpu(pdword[3]), cc);
Dean Anderson4de39f52010-03-03 19:39:19 -03001805 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001806 default:
sensoray-devf5402002014-01-29 15:24:07 -03001807 pr_info("s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001808 }
1809 default:
1810 pdata++;
1811 break;
1812 }
1813 if (bframe)
1814 break;
1815 } /* for */
1816 if (!bframe)
1817 return -EINVAL;
1818 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001819 vc = &dev->vc[dev->cc];
1820 idx = vc->cur_frame;
1821 frm = &vc->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001822 /* search done. now find out if should be acquiring on this channel */
sensoray-dev340a30c2014-02-12 17:25:45 -03001823 if (!vb2_is_streaming(&vc->vb_vidq)) {
Dean Anderson14d96262008-08-25 13:58:55 -03001824 /* we found a frame, but this channel is turned off */
1825 frm->ulState = S2255_READ_IDLE;
1826 return -EINVAL;
1827 }
1828
1829 if (frm->ulState == S2255_READ_IDLE) {
1830 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03001831 frm->cur_size = 0;
1832 }
1833
Dean Anderson14d96262008-08-25 13:58:55 -03001834 /* skip the marker 512 bytes (and offset if out of sync) */
1835 psrc = (u8 *)pipe_info->transfer_buffer + offset;
1836
Dean Anderson38f993a2008-06-26 23:15:51 -03001837
1838 if (frm->lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03001839 dprintk(dev, 1, "s2255 frame buffer == NULL.%p %p %d %d",
Dean Anderson38f993a2008-06-26 23:15:51 -03001840 frm, dev, dev->cc, idx);
1841 return -ENOMEM;
1842 }
1843
1844 pdest = frm->lpvbits + frm->cur_size;
1845
Dean Anderson14d96262008-08-25 13:58:55 -03001846 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03001847
Dean Anderson5e950fa2014-02-04 18:16:24 -03001848 size = vc->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001849
Dean Anderson14d96262008-08-25 13:58:55 -03001850 /* sanity check on pdest */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001851 if ((copy_size + frm->cur_size) < vc->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03001852 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001853
Dean Anderson38f993a2008-06-26 23:15:51 -03001854 frm->cur_size += copy_size;
sensoray-devf5402002014-01-29 15:24:07 -03001855 dprintk(dev, 4, "cur_size: %lu, size: %lu\n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001856
Dean Anderson14d96262008-08-25 13:58:55 -03001857 if (frm->cur_size >= size) {
sensoray-devf5402002014-01-29 15:24:07 -03001858 dprintk(dev, 2, "******[%d]Buffer[%d]full*******\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001859 dev->cc, idx);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001860 vc->last_frame = vc->cur_frame;
1861 vc->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03001862 /* end of system frame ring buffer, start at zero */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001863 if ((vc->cur_frame == SYS_FRAMES) ||
1864 (vc->cur_frame == vc->buffer.dwFrames))
1865 vc->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001866 /* frame ready */
sensoray-dev340a30c2014-02-12 17:25:45 -03001867 if (vb2_is_streaming(&vc->vb_vidq))
Dean Anderson5e950fa2014-02-04 18:16:24 -03001868 s2255_got_frame(vc, vc->jpg_size);
1869 vc->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03001870 frm->ulState = S2255_READ_IDLE;
1871 frm->cur_size = 0;
1872
Dean Anderson38f993a2008-06-26 23:15:51 -03001873 }
1874 /* done successfully */
1875 return 0;
1876}
1877
1878static void s2255_read_video_callback(struct s2255_dev *dev,
1879 struct s2255_pipeinfo *pipe_info)
1880{
1881 int res;
sensoray-devf5402002014-01-29 15:24:07 -03001882 dprintk(dev, 50, "callback read video\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001883
1884 if (dev->cc >= MAX_CHANNELS) {
1885 dev->cc = 0;
1886 dev_err(&dev->udev->dev, "invalid channel\n");
1887 return;
1888 }
1889 /* otherwise copy to the system buffers */
1890 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03001891 if (res != 0)
sensoray-devf5402002014-01-29 15:24:07 -03001892 dprintk(dev, 4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001893
sensoray-devf5402002014-01-29 15:24:07 -03001894 dprintk(dev, 50, "callback read video done\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001895 return;
1896}
1897
1898static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
1899 u16 Index, u16 Value, void *TransferBuffer,
1900 s32 TransferBufferLength, int bOut)
1901{
1902 int r;
1903 if (!bOut) {
1904 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
1905 Request,
1906 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
1907 USB_DIR_IN,
1908 Value, Index, TransferBuffer,
1909 TransferBufferLength, HZ * 5);
1910 } else {
1911 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
1912 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1913 Value, Index, TransferBuffer,
1914 TransferBufferLength, HZ * 5);
1915 }
1916 return r;
1917}
1918
1919/*
1920 * retrieve FX2 firmware version. future use.
1921 * @param dev pointer to device extension
1922 * @return -1 for fail, else returns firmware version as an int(16 bits)
1923 */
1924static int s2255_get_fx2fw(struct s2255_dev *dev)
1925{
1926 int fw;
1927 int ret;
1928 unsigned char transBuffer[64];
1929 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
1930 S2255_VR_IN);
1931 if (ret < 0)
sensoray-devf5402002014-01-29 15:24:07 -03001932 dprintk(dev, 2, "get fw error: %x\n", ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001933 fw = transBuffer[0] + (transBuffer[1] << 8);
sensoray-devf5402002014-01-29 15:24:07 -03001934 dprintk(dev, 2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
Dean Anderson38f993a2008-06-26 23:15:51 -03001935 return fw;
1936}
1937
1938/*
1939 * Create the system ring buffer to copy frames into from the
1940 * usb read pipe.
1941 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001942static int s2255_create_sys_buffers(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03001943{
1944 unsigned long i;
1945 unsigned long reqsize;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001946 vc->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03001947 /* always allocate maximum size(PAL) for system buffers */
1948 reqsize = SYS_FRAMES_MAXSIZE;
1949
1950 if (reqsize > SYS_FRAMES_MAXSIZE)
1951 reqsize = SYS_FRAMES_MAXSIZE;
1952
1953 for (i = 0; i < SYS_FRAMES; i++) {
1954 /* allocate the frames */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001955 vc->buffer.frame[i].lpvbits = vmalloc(reqsize);
1956 vc->buffer.frame[i].size = reqsize;
1957 if (vc->buffer.frame[i].lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03001958 pr_info("out of memory. using less frames\n");
Dean Anderson5e950fa2014-02-04 18:16:24 -03001959 vc->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03001960 break;
1961 }
1962 }
1963
1964 /* make sure internal states are set */
1965 for (i = 0; i < SYS_FRAMES; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001966 vc->buffer.frame[i].ulState = 0;
1967 vc->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001968 }
1969
Dean Anderson5e950fa2014-02-04 18:16:24 -03001970 vc->cur_frame = 0;
1971 vc->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03001972 return 0;
1973}
1974
Dean Anderson5e950fa2014-02-04 18:16:24 -03001975static int s2255_release_sys_buffers(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03001976{
1977 unsigned long i;
Dean Anderson38f993a2008-06-26 23:15:51 -03001978 for (i = 0; i < SYS_FRAMES; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001979 if (vc->buffer.frame[i].lpvbits)
1980 vfree(vc->buffer.frame[i].lpvbits);
1981 vc->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001982 }
1983 return 0;
1984}
1985
1986static int s2255_board_init(struct s2255_dev *dev)
1987{
Dean Anderson38f993a2008-06-26 23:15:51 -03001988 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
1989 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03001990 int j;
1991 struct s2255_pipeinfo *pipe = &dev->pipe;
sensoray-devf5402002014-01-29 15:24:07 -03001992 dprintk(dev, 4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03001993 memset(pipe, 0, sizeof(*pipe));
1994 pipe->dev = dev;
1995 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
1996 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001997
Dean Andersonab85c6a2010-04-08 23:39:12 -03001998 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
1999 GFP_KERNEL);
2000 if (pipe->transfer_buffer == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03002001 dprintk(dev, 1, "out of memory!\n");
Dean Andersonab85c6a2010-04-08 23:39:12 -03002002 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002003 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002004 /* query the firmware */
2005 fw_ver = s2255_get_fx2fw(dev);
2006
sensoray-devf5402002014-01-29 15:24:07 -03002007 pr_info("s2255: usb firmware version %d.%d\n",
2008 (fw_ver >> 8) & 0xff,
2009 fw_ver & 0xff);
Dean Andersonabce21f2009-04-23 16:04:41 -03002010
2011 if (fw_ver < S2255_CUR_USB_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002012 pr_info("s2255: newer USB firmware available\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002013
2014 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002015 struct s2255_vc *vc = &dev->vc[j];
Dean Anderson5e950fa2014-02-04 18:16:24 -03002016 vc->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002017 if (dev->pid == 0x2257 && j > 1)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002018 vc->mode.color |= (1 << 16);
2019 vc->jpegqual = S2255_DEF_JPEG_QUAL;
2020 vc->width = LINE_SZ_4CIFS_NTSC;
2021 vc->height = NUM_LINES_4CIFS_NTSC * 2;
2022 vc->std = V4L2_STD_NTSC_M;
2023 vc->fmt = &formats[0];
2024 vc->mode.restart = 1;
2025 vc->req_image_size = get_transfer_size(&mode_def);
2026 vc->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002027 /* create the system buffers */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002028 s2255_create_sys_buffers(vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03002029 }
2030 /* start read pipe */
2031 s2255_start_readpipe(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002032 dprintk(dev, 1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002033 return 0;
2034}
2035
2036static int s2255_board_shutdown(struct s2255_dev *dev)
2037{
2038 u32 i;
sensoray-devf5402002014-01-29 15:24:07 -03002039 dprintk(dev, 1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002040
2041 for (i = 0; i < MAX_CHANNELS; i++) {
sensoray-dev340a30c2014-02-12 17:25:45 -03002042 if (vb2_is_streaming(&dev->vc[i].vb_vidq))
Dean Anderson5e950fa2014-02-04 18:16:24 -03002043 s2255_stop_acquire(&dev->vc[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002044 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002045 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002046 for (i = 0; i < MAX_CHANNELS; i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002047 s2255_release_sys_buffers(&dev->vc[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002048 /* release transfer buffer */
2049 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002050 return 0;
2051}
2052
2053static void read_pipe_completion(struct urb *purb)
2054{
2055 struct s2255_pipeinfo *pipe_info;
2056 struct s2255_dev *dev;
2057 int status;
2058 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002059 pipe_info = purb->context;
Dean Anderson38f993a2008-06-26 23:15:51 -03002060 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002061 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002062 return;
2063 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002064 dev = pipe_info->dev;
2065 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002066 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002067 return;
2068 }
2069 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002070 /* if shutting down, do not resubmit, exit immediately */
2071 if (status == -ESHUTDOWN) {
sensoray-devf5402002014-01-29 15:24:07 -03002072 dprintk(dev, 2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002073 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002074 return;
2075 }
2076
2077 if (pipe_info->state == 0) {
sensoray-devf5402002014-01-29 15:24:07 -03002078 dprintk(dev, 2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002079 return;
2080 }
2081
Dean Andersonb02064c2009-04-30 12:29:38 -03002082 if (status == 0)
2083 s2255_read_video_callback(dev, pipe_info);
2084 else {
2085 pipe_info->err_count++;
sensoray-devf5402002014-01-29 15:24:07 -03002086 dprintk(dev, 1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002087 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002088
Dean Anderson38f993a2008-06-26 23:15:51 -03002089 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2090 /* reuse urb */
2091 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2092 pipe,
2093 pipe_info->transfer_buffer,
2094 pipe_info->cur_transfer_size,
2095 read_pipe_completion, pipe_info);
2096
2097 if (pipe_info->state != 0) {
sensoray-devf5402002014-01-29 15:24:07 -03002098 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC))
Dean Anderson38f993a2008-06-26 23:15:51 -03002099 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002100 } else {
sensoray-devf5402002014-01-29 15:24:07 -03002101 dprintk(dev, 2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002102 }
2103 return;
2104}
2105
2106static int s2255_start_readpipe(struct s2255_dev *dev)
2107{
2108 int pipe;
2109 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002110 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002111 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
sensoray-devf5402002014-01-29 15:24:07 -03002112 dprintk(dev, 2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002113 pipe_info->state = 1;
2114 pipe_info->err_count = 0;
2115 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2116 if (!pipe_info->stream_urb) {
2117 dev_err(&dev->udev->dev,
2118 "ReadStream: Unable to alloc URB\n");
2119 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002120 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002121 /* transfer buffer allocated in board_init */
2122 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2123 pipe,
2124 pipe_info->transfer_buffer,
2125 pipe_info->cur_transfer_size,
2126 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002127 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2128 if (retval) {
sensoray-devf5402002014-01-29 15:24:07 -03002129 pr_err("s2255: start read pipe failed\n");
Dean Andersonab85c6a2010-04-08 23:39:12 -03002130 return retval;
2131 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002132 return 0;
2133}
2134
2135/* starts acquisition process */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002136static int s2255_start_acquire(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03002137{
Dean Anderson38f993a2008-06-26 23:15:51 -03002138 int res;
2139 unsigned long chn_rev;
2140 int j;
Dean Anderson5e950fa2014-02-04 18:16:24 -03002141 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03002142 __le32 *buffer = dev->cmdbuf;
Dean Anderson38f993a2008-06-26 23:15:51 -03002143
Dean Anderson47d8c882014-02-05 15:43:51 -03002144 mutex_lock(&dev->cmdlock);
2145 chn_rev = G_chnmap[vc->idx];
Dean Anderson5e950fa2014-02-04 18:16:24 -03002146 vc->last_frame = -1;
2147 vc->bad_payload = 0;
2148 vc->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002149 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002150 vc->buffer.frame[j].ulState = 0;
2151 vc->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002152 }
2153
2154 /* send the start command */
Dean Anderson47d8c882014-02-05 15:43:51 -03002155 buffer[0] = IN_DATA_TOKEN;
2156 buffer[1] = (__le32) cpu_to_le32(chn_rev);
2157 buffer[2] = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002158 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2159 if (res != 0)
2160 dev_err(&dev->udev->dev, "CMD_START error\n");
2161
Dean Anderson5e950fa2014-02-04 18:16:24 -03002162 dprintk(dev, 2, "start acquire exit[%d] %d\n", vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03002163 mutex_unlock(&dev->cmdlock);
Dean Anderson6a5b63b2014-02-05 15:58:20 -03002164 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002165}
2166
Dean Anderson5e950fa2014-02-04 18:16:24 -03002167static int s2255_stop_acquire(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03002168{
Dean Anderson38f993a2008-06-26 23:15:51 -03002169 int res;
2170 unsigned long chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03002171 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03002172 __le32 *buffer = dev->cmdbuf;
2173
2174 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03002175 chn_rev = G_chnmap[vc->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002176 /* send the stop command */
Dean Anderson47d8c882014-02-05 15:43:51 -03002177 buffer[0] = IN_DATA_TOKEN;
2178 buffer[1] = (__le32) cpu_to_le32(chn_rev);
2179 buffer[2] = CMD_STOP;
2180
Dean Anderson38f993a2008-06-26 23:15:51 -03002181 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002182 if (res != 0)
2183 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson47d8c882014-02-05 15:43:51 -03002184
Dean Anderson5e950fa2014-02-04 18:16:24 -03002185 dprintk(dev, 4, "%s: chn %d, res %d\n", __func__, vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03002186 mutex_unlock(&dev->cmdlock);
Dean Anderson14d96262008-08-25 13:58:55 -03002187 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002188}
2189
2190static void s2255_stop_readpipe(struct s2255_dev *dev)
2191{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002192 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002193
Dean Andersonab85c6a2010-04-08 23:39:12 -03002194 pipe->state = 0;
2195 if (pipe->stream_urb) {
2196 /* cancel urb */
2197 usb_kill_urb(pipe->stream_urb);
2198 usb_free_urb(pipe->stream_urb);
2199 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002200 }
sensoray-devf5402002014-01-29 15:24:07 -03002201 dprintk(dev, 4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002202 return;
2203}
2204
Dean Anderson14d96262008-08-25 13:58:55 -03002205static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002206{
Dean Anderson14d96262008-08-25 13:58:55 -03002207 if (reset)
2208 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002209 dev->fw_data->fw_size = dev->fw_data->fw->size;
2210 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2211 memcpy(dev->fw_data->pfw_data,
2212 dev->fw_data->fw->data, CHUNK_SIZE);
2213 dev->fw_data->fw_loaded = CHUNK_SIZE;
2214 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2215 usb_sndbulkpipe(dev->udev, 2),
2216 dev->fw_data->pfw_data,
2217 CHUNK_SIZE, s2255_fwchunk_complete,
2218 dev->fw_data);
2219 mod_timer(&dev->timer, jiffies + HZ);
2220}
2221
2222/* standard usb probe function */
2223static int s2255_probe(struct usb_interface *interface,
2224 const struct usb_device_id *id)
2225{
2226 struct s2255_dev *dev = NULL;
2227 struct usb_host_interface *iface_desc;
2228 struct usb_endpoint_descriptor *endpoint;
2229 int i;
2230 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002231 __le32 *pdata;
2232 int fw_size;
Dean Anderson47d8c882014-02-05 15:43:51 -03002233
Dean Anderson38f993a2008-06-26 23:15:51 -03002234 /* allocate memory for our device state and initialize it to zero */
2235 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2236 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002237 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002238 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002239 }
Dean Anderson47d8c882014-02-05 15:43:51 -03002240
2241 dev->cmdbuf = kzalloc(S2255_CMDBUF_SIZE, GFP_KERNEL);
2242 if (dev->cmdbuf == NULL) {
2243 s2255_dev_err(&interface->dev, "out of memory\n");
Daeseok Youne21c94e2014-05-08 19:57:18 -03002244 goto errorFWDATA1;
Dean Anderson47d8c882014-02-05 15:43:51 -03002245 }
2246
Dean Andersonfe85ce92010-06-01 19:12:07 -03002247 atomic_set(&dev->num_channels, 0);
Hans Verkuilff3ec572014-08-20 19:25:34 -03002248 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002249 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2250 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002251 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002252 mutex_init(&dev->lock);
Dean Anderson47d8c882014-02-05 15:43:51 -03002253 mutex_init(&dev->cmdlock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002254 /* grab usb_device and save it */
2255 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2256 if (dev->udev == NULL) {
2257 dev_err(&interface->dev, "null usb device\n");
2258 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002259 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002260 }
sensoray-devf5402002014-01-29 15:24:07 -03002261 dev_dbg(&interface->dev, "dev: %p, udev %p interface %p\n",
2262 dev, dev->udev, interface);
Dean Anderson38f993a2008-06-26 23:15:51 -03002263 dev->interface = interface;
2264 /* set up the endpoint information */
2265 iface_desc = interface->cur_altsetting;
sensoray-devf5402002014-01-29 15:24:07 -03002266 dev_dbg(&interface->dev, "num EP: %d\n",
2267 iface_desc->desc.bNumEndpoints);
Dean Anderson38f993a2008-06-26 23:15:51 -03002268 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2269 endpoint = &iface_desc->endpoint[i].desc;
2270 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2271 /* we found the bulk in endpoint */
2272 dev->read_endpoint = endpoint->bEndpointAddress;
2273 }
2274 }
2275
2276 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002277 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002278 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002279 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002280 init_timer(&dev->timer);
2281 dev->timer.function = s2255_timer;
2282 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002283 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002284 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002285 struct s2255_vc *vc = &dev->vc[i];
2286 vc->idx = i;
2287 vc->dev = dev;
2288 init_waitqueue_head(&vc->wait_setmode);
2289 init_waitqueue_head(&vc->wait_vidstatus);
sensoray-dev340a30c2014-02-12 17:25:45 -03002290 spin_lock_init(&vc->qlock);
2291 mutex_init(&vc->vb_lock);
Dean Anderson4de39f52010-03-03 19:39:19 -03002292 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002293
2294 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002295 if (!dev->fw_data->fw_urb) {
2296 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002297 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002298 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002299
Dean Anderson38f993a2008-06-26 23:15:51 -03002300 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2301 if (!dev->fw_data->pfw_data) {
2302 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002303 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002304 }
2305 /* load the first chunk */
2306 if (request_firmware(&dev->fw_data->fw,
2307 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
sensoray-devf5402002014-01-29 15:24:07 -03002308 dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002309 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002310 }
Dean Anderson14d96262008-08-25 13:58:55 -03002311 /* check the firmware is valid */
2312 fw_size = dev->fw_data->fw->size;
2313 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002314
Dean Anderson14d96262008-08-25 13:58:55 -03002315 if (*pdata != S2255_FW_MARKER) {
sensoray-devf5402002014-01-29 15:24:07 -03002316 dev_err(&interface->dev, "Firmware invalid.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002317 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002318 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002319 } else {
2320 /* make sure firmware is the latest */
2321 __le32 *pRel;
2322 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
sensoray-devf5402002014-01-29 15:24:07 -03002323 pr_info("s2255 dsp fw version %x\n", le32_to_cpu(*pRel));
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002324 dev->dsp_fw_ver = le32_to_cpu(*pRel);
2325 if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002326 pr_info("s2255: f2255usb.bin out of date.\n");
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002327 if (dev->pid == 0x2257 &&
2328 dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
sensoray-devf5402002014-01-29 15:24:07 -03002329 pr_warn("2257 needs firmware %d or above.\n",
2330 S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002331 }
Dean Anderson14d96262008-08-25 13:58:55 -03002332 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002333 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002334 retval = s2255_board_init(dev);
2335 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002336 goto errorBOARDINIT;
Dean Anderson14d96262008-08-25 13:58:55 -03002337 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002338 /* loads v4l specific */
2339 retval = s2255_probe_v4l(dev);
2340 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002341 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002342 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2343 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002344errorBOARDINIT:
2345 s2255_board_shutdown(dev);
2346errorFWMARKER:
2347 release_firmware(dev->fw_data->fw);
2348errorREQFW:
2349 kfree(dev->fw_data->pfw_data);
2350errorFWDATA2:
2351 usb_free_urb(dev->fw_data->fw_urb);
2352errorFWURB:
Kirill Tkhai9f6be2b2014-04-17 17:47:04 -03002353 del_timer_sync(&dev->timer);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002354errorEP:
2355 usb_put_dev(dev->udev);
2356errorUDEV:
2357 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002358 mutex_destroy(&dev->lock);
2359errorFWDATA1:
Dean Anderson47d8c882014-02-05 15:43:51 -03002360 kfree(dev->cmdbuf);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002361 kfree(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002362 pr_warn("Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002363 return retval;
2364}
2365
2366/* disconnect routine. when board is removed physically or with rmmod */
2367static void s2255_disconnect(struct usb_interface *interface)
2368{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002369 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002370 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002371 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002372 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002373 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002374 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002375 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002376 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002377 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002378 for (i = 0; i < channels; i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002379 video_unregister_device(&dev->vc[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002380 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002381 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2382 wake_up(&dev->fw_data->wait_fw);
2383 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002384 dev->vc[i].setmode_ready = 1;
2385 wake_up(&dev->vc[i].wait_setmode);
2386 dev->vc[i].vidstatus_ready = 1;
2387 wake_up(&dev->vc[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002388 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002389 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002390 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002391 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002392}
2393
2394static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002395 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002396 .probe = s2255_probe,
2397 .disconnect = s2255_disconnect,
2398 .id_table = s2255_table,
2399};
2400
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002401module_usb_driver(s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002402
2403MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2404MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2405MODULE_LICENSE("GPL");
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03002406MODULE_VERSION(S2255_VERSION);
Tim Gardner1bec9822012-07-24 16:52:27 -03002407MODULE_FIRMWARE(FIRMWARE_FILE_NAME);