blob: 9acdaa3716fbea1503ec90791fa09ad15d750da5 [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>
Junghak Sung2d700712015-09-22 10:30:30 -030048#include <media/videobuf2-v4l2.h>
sensoray-dev340a30c2014-02-12 17:25:45 -030049#include <media/videobuf2-vmalloc.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030050#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030051#include <media/v4l2-device.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030052#include <media/v4l2-ioctl.h>
Hans Verkuil192f1e72013-02-15 05:51:21 -030053#include <media/v4l2-ctrls.h>
Hans Verkuil44d06d82013-02-15 05:59:00 -030054#include <media/v4l2-event.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030055
sensoray-dev340a30c2014-02-12 17:25:45 -030056#define S2255_VERSION "1.25.1"
Dean Anderson38f993a2008-06-26 23:15:51 -030057#define FIRMWARE_FILE_NAME "f2255usb.bin"
58
Dean Anderson22b88d42008-08-29 15:33:19 -030059/* default JPEG quality */
60#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030061/* vendor request in */
62#define S2255_VR_IN 0
63/* vendor request out */
64#define S2255_VR_OUT 1
65/* firmware query */
66#define S2255_VR_FW 0x30
67/* USB endpoint number for configuring the device */
68#define S2255_CONFIG_EP 2
69/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030070#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030071/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030072#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson9da62eb2014-02-05 14:58:06 -030073#define S2255_MIN_BUFS 2
Dean Anderson14d96262008-08-25 13:58:55 -030074#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030075#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030076#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
77#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
78#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
79#define S2255_RESPONSE_FW cpu_to_le32(0x10)
80#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030081#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030082#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030083#define SYS_FRAMES 4
84/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030085#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
86#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030087#define LINE_SZ_4CIFS_NTSC 640
88#define LINE_SZ_2CIFS_NTSC 640
89#define LINE_SZ_1CIFS_NTSC 320
90#define LINE_SZ_4CIFS_PAL 704
91#define LINE_SZ_2CIFS_PAL 704
92#define LINE_SZ_1CIFS_PAL 352
93#define NUM_LINES_4CIFS_NTSC 240
94#define NUM_LINES_2CIFS_NTSC 240
95#define NUM_LINES_1CIFS_NTSC 240
96#define NUM_LINES_4CIFS_PAL 288
97#define NUM_LINES_2CIFS_PAL 288
98#define NUM_LINES_1CIFS_PAL 288
99#define LINE_SZ_DEF 640
100#define NUM_LINES_DEF 240
101
102
103/* predefined settings */
104#define FORMAT_NTSC 1
105#define FORMAT_PAL 2
106
107#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
108#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
109#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300110/* SCALE_4CIFSI is the 2 fields interpolated into one */
111#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300112
113#define COLOR_YUVPL 1 /* YUV planar */
114#define COLOR_YUVPK 2 /* YUV packed */
115#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300116#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300117
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300118#define MASK_COLOR 0x000000ff
119#define MASK_JPG_QUALITY 0x0000ff00
120#define MASK_INPUT_TYPE 0x000f0000
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300121/* frame decimation. */
Dean Anderson38f993a2008-06-26 23:15:51 -0300122#define FDEC_1 1 /* capture every frame. default */
123#define FDEC_2 2 /* capture every 2nd frame */
124#define FDEC_3 3 /* capture every 3rd frame */
125#define FDEC_5 5 /* capture every 5th frame */
126
127/*-------------------------------------------------------
128 * Default mode parameters.
129 *-------------------------------------------------------*/
130#define DEF_SCALE SCALE_4CIFS
131#define DEF_COLOR COLOR_YUVPL
132#define DEF_FDEC FDEC_1
133#define DEF_BRIGHT 0
134#define DEF_CONTRAST 0x5c
135#define DEF_SATURATION 0x80
136#define DEF_HUE 0
137
138/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300139#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
Dan Carpenter3b2a6302012-02-17 02:44:10 -0300140#define CMD_2255 0xc2255000
Dean Anderson3fa00602010-03-04 20:47:33 -0300141#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
142#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
143#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
144#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300145
146struct s2255_mode {
147 u32 format; /* input video format (NTSC, PAL) */
148 u32 scale; /* output video scale */
149 u32 color; /* output video color format */
150 u32 fdec; /* frame decimation */
151 u32 bright; /* brightness */
152 u32 contrast; /* contrast */
153 u32 saturation; /* saturation */
154 u32 hue; /* hue (NTSC only)*/
155 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
156 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
157 u32 restart; /* if DSP requires restart */
158};
159
Dean Anderson14d96262008-08-25 13:58:55 -0300160
161#define S2255_READ_IDLE 0
162#define S2255_READ_FRAME 1
163
Dean Anderson38f993a2008-06-26 23:15:51 -0300164/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300165struct s2255_framei {
166 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300167 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300168 void *lpvbits; /* image data */
169 unsigned long cur_size; /* current data copied to it */
170};
171
172/* image buffer structure */
173struct s2255_bufferi {
174 unsigned long dwFrames; /* number of frames in buffer */
175 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
176};
177
178#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
179 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300180 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300181
Dean Anderson38f993a2008-06-26 23:15:51 -0300182/* for firmware loading, fw_state */
183#define S2255_FW_NOTLOADED 0
184#define S2255_FW_LOADED_DSPWAIT 1
185#define S2255_FW_SUCCESS 2
186#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300187#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300188#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300189/* 2255 read states */
190#define S2255_READ_IDLE 0
191#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300192struct s2255_fw {
193 int fw_loaded;
194 int fw_size;
195 struct urb *fw_urb;
196 atomic_t fw_state;
197 void *pfw_data;
198 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300199 const struct firmware *fw;
200};
201
202struct s2255_pipeinfo {
203 u32 max_transfer_size;
204 u32 cur_transfer_size;
205 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300206 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300207 void *stream_urb;
208 void *dev; /* back pointer to s2255_dev struct*/
209 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300210 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300211};
212
213struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300214struct s2255_dev;
215
Dean Anderson5e950fa2014-02-04 18:16:24 -0300216/* 2255 video channel */
217struct s2255_vc {
sensoray-devf5402002014-01-29 15:24:07 -0300218 struct s2255_dev *dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300219 struct video_device vdev;
Hans Verkuil192f1e72013-02-15 05:51:21 -0300220 struct v4l2_ctrl_handler hdl;
Hans Verkuil7041dec2013-02-15 05:53:45 -0300221 struct v4l2_ctrl *jpegqual_ctrl;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300222 int resources;
Dean Andersond86c6a82014-02-04 17:18:03 -0300223 struct list_head buf_list;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300224 struct s2255_bufferi buffer;
225 struct s2255_mode mode;
Hans Verkuil469af772013-02-15 06:12:58 -0300226 v4l2_std_id std;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300227 /* jpeg compression */
Hans Verkuil7041dec2013-02-15 05:53:45 -0300228 unsigned jpegqual;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300229 /* capture parameters (for high quality mode full size) */
230 struct v4l2_captureparm cap_parm;
231 int cur_frame;
232 int last_frame;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300233 /* allocated image size */
234 unsigned long req_image_size;
235 /* received packet size */
236 unsigned long pkt_size;
237 int bad_payload;
238 unsigned long frame_count;
239 /* if JPEG image */
240 int jpg_size;
241 /* if channel configured to default state */
242 int configured;
243 wait_queue_head_t wait_setmode;
244 int setmode_ready;
245 /* video status items */
246 int vidstatus;
247 wait_queue_head_t wait_vidstatus;
248 int vidstatus_ready;
249 unsigned int width;
250 unsigned int height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300251 enum v4l2_field field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300252 const struct s2255_fmt *fmt;
253 int idx; /* channel number on device, 0-3 */
sensoray-dev340a30c2014-02-12 17:25:45 -0300254 struct vb2_queue vb_vidq;
255 struct mutex vb_lock; /* streaming lock */
256 spinlock_t qlock;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300257};
258
Dean Anderson38f993a2008-06-26 23:15:51 -0300259
260struct s2255_dev {
Dean Anderson5e950fa2014-02-04 18:16:24 -0300261 struct s2255_vc vc[MAX_CHANNELS];
sensoray-devf5402002014-01-29 15:24:07 -0300262 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300263 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300264 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300265 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson47d8c882014-02-05 15:43:51 -0300266 struct mutex cmdlock; /* protects cmdbuf */
Dean Anderson38f993a2008-06-26 23:15:51 -0300267 struct usb_device *udev;
268 struct usb_interface *interface;
269 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300270 struct timer_list timer;
271 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300272 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300273 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300274 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300275 int chn_ready;
Dean Anderson4de39f52010-03-03 19:39:19 -0300276 /* dsp firmware version (f2255usb.bin) */
277 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300278 u16 pid; /* product id */
Dean Anderson47d8c882014-02-05 15:43:51 -0300279#define S2255_CMDBUF_SIZE 512
280 __le32 *cmdbuf;
Dean Anderson38f993a2008-06-26 23:15:51 -0300281};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300282
Dean Anderson65c6edb2010-04-20 17:21:32 -0300283static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
284{
285 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
286}
Dean Anderson38f993a2008-06-26 23:15:51 -0300287
288struct s2255_fmt {
289 char *name;
290 u32 fourcc;
291 int depth;
292};
293
294/* buffer for one video frame */
295struct s2255_buffer {
296 /* common v4l buffer stuff -- must be first */
Junghak Sung2d700712015-09-22 10:30:30 -0300297 struct vb2_v4l2_buffer vb;
sensoray-dev340a30c2014-02-12 17:25:45 -0300298 struct list_head list;
Dean Anderson38f993a2008-06-26 23:15:51 -0300299};
300
Dean Anderson38f993a2008-06-26 23:15:51 -0300301
Dean Andersonabce21f2009-04-23 16:04:41 -0300302/* current cypress EEPROM firmware version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300303#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
Dean Anderson4de39f52010-03-03 19:39:19 -0300304/* current DSP FW version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300305#define S2255_CUR_DSP_FWVER 10104
Dean Anderson4de39f52010-03-03 19:39:19 -0300306/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300307#define S2255_MIN_DSP_STATUS 5
308#define S2255_MIN_DSP_COLORFILTER 8
Hans Verkuil469af772013-02-15 06:12:58 -0300309#define S2255_NORMS (V4L2_STD_ALL)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300310
311/* private V4L2 controls */
312
313/*
314 * The following chart displays how COLORFILTER should be set
315 * =========================================================
316 * = fourcc = COLORFILTER =
317 * = ===============================
318 * = = 0 = 1 =
319 * =========================================================
320 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
321 * = = s-video or = composite =
322 * = = B/W camera = input =
323 * =========================================================
324 * = other = color, svideo = color, =
325 * = = = composite =
326 * =========================================================
327 *
328 * Notes:
329 * channels 0-3 on 2255 are composite
330 * channels 0-1 on 2257 are composite, 2-3 are s-video
331 * If COLORFILTER is 0 with a composite color camera connected,
332 * the output will appear monochrome but hatching
333 * will occur.
334 * COLORFILTER is different from "color killer" and "color effects"
335 * for reasons above.
336 */
337#define S2255_V4L2_YC_ON 1
338#define S2255_V4L2_YC_OFF 0
Hans Verkuil192f1e72013-02-15 05:51:21 -0300339#define V4L2_CID_S2255_COLORFILTER (V4L2_CID_USER_S2255_BASE + 0)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300340
Dean Anderson38f993a2008-06-26 23:15:51 -0300341/* frame prefix size (sent once every frame) */
342#define PREFIX_SIZE 512
343
344/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300345static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300346
Dean Anderson38f993a2008-06-26 23:15:51 -0300347static int debug;
Dean Anderson38f993a2008-06-26 23:15:51 -0300348
349static int s2255_start_readpipe(struct s2255_dev *dev);
350static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300351static int s2255_start_acquire(struct s2255_vc *vc);
352static int s2255_stop_acquire(struct s2255_vc *vc);
353static void s2255_fillbuff(struct s2255_vc *vc, struct s2255_buffer *buf,
Dean Andersonfe85ce92010-06-01 19:12:07 -0300354 int jpgsize);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300355static int s2255_set_mode(struct s2255_vc *vc, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300356static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300357static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300358static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300359static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
360 u16 index, u16 value, void *buf,
361 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300362
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300363/* dev_err macro with driver name */
364#define S2255_DRIVER_NAME "s2255"
365#define s2255_dev_err(dev, fmt, arg...) \
366 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
367
sensoray-devf5402002014-01-29 15:24:07 -0300368#define dprintk(dev, level, fmt, arg...) \
369 v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
Dean Anderson38f993a2008-06-26 23:15:51 -0300370
Dean Anderson38f993a2008-06-26 23:15:51 -0300371static struct usb_driver s2255_driver;
372
Dean Anderson38f993a2008-06-26 23:15:51 -0300373/* start video number */
374static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
375
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300376/* Enable jpeg capture. */
377static int jpeg_enable = 1;
378
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300379module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300380MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300381module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300382MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300383module_param(jpeg_enable, int, 0644);
384MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
Dean Anderson38f993a2008-06-26 23:15:51 -0300385
386/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300387#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300388static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300389 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
390 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300391 { } /* Terminating entry */
392};
393MODULE_DEVICE_TABLE(usb, s2255_table);
394
Dean Anderson38f993a2008-06-26 23:15:51 -0300395#define BUFFER_TIMEOUT msecs_to_jiffies(400)
396
Dean Anderson38f993a2008-06-26 23:15:51 -0300397/* image formats. */
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300398/* JPEG formats must be defined last to support jpeg_enable parameter */
Dean Anderson38f993a2008-06-26 23:15:51 -0300399static const struct s2255_fmt formats[] = {
400 {
Dean Anderson38f993a2008-06-26 23:15:51 -0300401 .name = "4:2:2, packed, YUYV",
402 .fourcc = V4L2_PIX_FMT_YUYV,
403 .depth = 16
404
405 }, {
406 .name = "4:2:2, packed, UYVY",
407 .fourcc = V4L2_PIX_FMT_UYVY,
408 .depth = 16
409 }, {
Hans Verkuil5c632b22013-02-26 14:29:04 -0300410 .name = "4:2:2, planar, YUV422P",
411 .fourcc = V4L2_PIX_FMT_YUV422P,
412 .depth = 16
413
414 }, {
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300415 .name = "8bpp GREY",
416 .fourcc = V4L2_PIX_FMT_GREY,
417 .depth = 8
418 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300419 .name = "JPG",
420 .fourcc = V4L2_PIX_FMT_JPEG,
421 .depth = 24
422 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300423 .name = "MJPG",
424 .fourcc = V4L2_PIX_FMT_MJPEG,
425 .depth = 24
Dean Anderson38f993a2008-06-26 23:15:51 -0300426 }
427};
428
Dean Anderson5e950fa2014-02-04 18:16:24 -0300429static int norm_maxw(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300430{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300431 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300432 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
433}
434
Dean Anderson5e950fa2014-02-04 18:16:24 -0300435static int norm_maxh(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300436{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300437 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300438 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
439}
440
Dean Anderson5e950fa2014-02-04 18:16:24 -0300441static int norm_minw(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300442{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300443 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300444 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
445}
446
Dean Anderson5e950fa2014-02-04 18:16:24 -0300447static int norm_minh(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300448{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300449 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300450 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
451}
452
453
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300454/*
455 * TODO: fixme: move YUV reordering to hardware
456 * converts 2255 planar format to yuyv or uyvy
457 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300458static void planar422p_to_yuv_packed(const unsigned char *in,
459 unsigned char *out,
460 int width, int height,
461 int fmt)
462{
463 unsigned char *pY;
464 unsigned char *pCb;
465 unsigned char *pCr;
466 unsigned long size = height * width;
467 unsigned int i;
468 pY = (unsigned char *)in;
469 pCr = (unsigned char *)in + height * width;
470 pCb = (unsigned char *)in + height * width + (height * width / 2);
471 for (i = 0; i < size * 2; i += 4) {
472 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
473 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
474 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
475 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
476 }
477 return;
478}
479
Hans Verkuild45b9b82008-09-04 03:33:43 -0300480static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300481{
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300482 s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
sensoray-devf5402002014-01-29 15:24:07 -0300483 msleep(20);
Dean Anderson14d96262008-08-25 13:58:55 -0300484 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300485 msleep(600);
486 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300487 return;
488}
Dean Anderson38f993a2008-06-26 23:15:51 -0300489
490/* kickstarts the firmware loading. from probe
491 */
492static void s2255_timer(unsigned long user_data)
493{
494 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson38f993a2008-06-26 23:15:51 -0300495 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
sensoray-devf5402002014-01-29 15:24:07 -0300496 pr_err("s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300497 atomic_set(&data->fw_state, S2255_FW_FAILED);
498 /* wake up anything waiting for the firmware */
499 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300500 return;
501 }
502}
503
Dean Anderson38f993a2008-06-26 23:15:51 -0300504
505/* this loads the firmware asynchronously.
Hans Verkuil0b84caa2013-02-26 14:14:19 -0300506 Originally this was done synchronously in probe.
Dean Anderson38f993a2008-06-26 23:15:51 -0300507 But it is better to load it asynchronously here than block
508 inside the probe function. Blocking inside probe affects boot time.
509 FW loading is triggered by the timer in the probe function
510*/
511static void s2255_fwchunk_complete(struct urb *urb)
512{
513 struct s2255_fw *data = urb->context;
514 struct usb_device *udev = urb->dev;
515 int len;
Dean Anderson38f993a2008-06-26 23:15:51 -0300516 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300517 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300518 atomic_set(&data->fw_state, S2255_FW_FAILED);
519 /* wake up anything waiting for the firmware */
520 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300521 return;
522 }
523 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300524 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300525 atomic_set(&data->fw_state, S2255_FW_FAILED);
526 /* wake up anything waiting for the firmware */
527 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300528 return;
529 }
530#define CHUNK_SIZE 512
531 /* all USB transfers must be done with continuous kernel memory.
532 can't allocate more than 128k in current linux kernel, so
533 upload the firmware in chunks
534 */
535 if (data->fw_loaded < data->fw_size) {
536 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
537 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
538
539 if (len < CHUNK_SIZE)
540 memset(data->pfw_data, 0, CHUNK_SIZE);
541
Dean Anderson38f993a2008-06-26 23:15:51 -0300542 memcpy(data->pfw_data,
543 (char *) data->fw->data + data->fw_loaded, len);
544
545 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
546 data->pfw_data, CHUNK_SIZE,
547 s2255_fwchunk_complete, data);
548 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
549 dev_err(&udev->dev, "failed submit URB\n");
550 atomic_set(&data->fw_state, S2255_FW_FAILED);
551 /* wake up anything waiting for the firmware */
552 wake_up(&data->wait_fw);
553 return;
554 }
555 data->fw_loaded += len;
sensoray-devf5402002014-01-29 15:24:07 -0300556 } else
Dean Anderson38f993a2008-06-26 23:15:51 -0300557 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson38f993a2008-06-26 23:15:51 -0300558 return;
559
560}
561
sensoray-dev9694fbe2014-11-04 17:34:03 -0300562static void s2255_got_frame(struct s2255_vc *vc, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300563{
Dean Anderson38f993a2008-06-26 23:15:51 -0300564 struct s2255_buffer *buf;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300565 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300566 unsigned long flags = 0;
sensoray-dev9694fbe2014-11-04 17:34:03 -0300567
sensoray-dev340a30c2014-02-12 17:25:45 -0300568 spin_lock_irqsave(&vc->qlock, flags);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300569 if (list_empty(&vc->buf_list)) {
sensoray-devf5402002014-01-29 15:24:07 -0300570 dprintk(dev, 1, "No active queue to serve\n");
sensoray-dev9694fbe2014-11-04 17:34:03 -0300571 spin_unlock_irqrestore(&vc->qlock, flags);
572 return;
Dean Anderson38f993a2008-06-26 23:15:51 -0300573 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300574 buf = list_entry(vc->buf_list.next,
sensoray-dev340a30c2014-02-12 17:25:45 -0300575 struct s2255_buffer, list);
576 list_del(&buf->list);
Junghak Sungd6dd6452015-11-03 08:16:37 -0200577 buf->vb.vb2_buf.timestamp = ktime_get_ns();
Junghak Sung2d700712015-09-22 10:30:30 -0300578 buf->vb.field = vc->field;
579 buf->vb.sequence = vc->frame_count;
sensoray-dev340a30c2014-02-12 17:25:45 -0300580 spin_unlock_irqrestore(&vc->qlock, flags);
sensoray-dev9694fbe2014-11-04 17:34:03 -0300581
582 s2255_fillbuff(vc, buf, jpgsize);
583 /* tell v4l buffer was filled */
Junghak Sung2d700712015-09-22 10:30:30 -0300584 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
sensoray-dev9694fbe2014-11-04 17:34:03 -0300585 dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf);
Dean Anderson38f993a2008-06-26 23:15:51 -0300586}
587
Dean Anderson38f993a2008-06-26 23:15:51 -0300588static const struct s2255_fmt *format_by_fourcc(int fourcc)
589{
590 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300591 for (i = 0; i < ARRAY_SIZE(formats); i++) {
592 if (-1 == formats[i].fourcc)
593 continue;
sensoray-devf5402002014-01-29 15:24:07 -0300594 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
595 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
596 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300597 if (formats[i].fourcc == fourcc)
598 return formats + i;
599 }
600 return NULL;
601}
602
Dean Anderson38f993a2008-06-26 23:15:51 -0300603/* video buffer vmalloc implementation based partly on VIVI driver which is
604 * Copyright (c) 2006 by
605 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
606 * Ted Walther <ted--a.t--enumera.com>
607 * John Sokol <sokol--a.t--videotechnology.com>
608 * http://v4l.videotechnology.com/
609 *
610 */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300611static void s2255_fillbuff(struct s2255_vc *vc,
Dean Andersonfe85ce92010-06-01 19:12:07 -0300612 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300613{
614 int pos = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300615 const char *tmpbuf;
Junghak Sung2d700712015-09-22 10:30:30 -0300616 char *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
Dean Anderson38f993a2008-06-26 23:15:51 -0300617 unsigned long last_frame;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300618 struct s2255_dev *dev = vc->dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300619
620 if (!vbuf)
621 return;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300622 last_frame = vc->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300623 if (last_frame != -1) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300624 tmpbuf =
Dean Anderson5e950fa2014-02-04 18:16:24 -0300625 (const char *)vc->buffer.frame[last_frame].lpvbits;
Dean Anderson8bf405a2014-02-05 15:18:55 -0300626 switch (vc->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300627 case V4L2_PIX_FMT_YUYV:
628 case V4L2_PIX_FMT_UYVY:
629 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
sensoray-dev340a30c2014-02-12 17:25:45 -0300630 vbuf, vc->width,
631 vc->height,
Dean Anderson8bf405a2014-02-05 15:18:55 -0300632 vc->fmt->fourcc);
Dean Anderson38f993a2008-06-26 23:15:51 -0300633 break;
634 case V4L2_PIX_FMT_GREY:
sensoray-dev340a30c2014-02-12 17:25:45 -0300635 memcpy(vbuf, tmpbuf, vc->width * vc->height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300636 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300637 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300638 case V4L2_PIX_FMT_MJPEG:
Junghak Sung2d700712015-09-22 10:30:30 -0300639 vb2_set_plane_payload(&buf->vb.vb2_buf, 0, jpgsize);
sensoray-dev340a30c2014-02-12 17:25:45 -0300640 memcpy(vbuf, tmpbuf, jpgsize);
Dean Anderson14d96262008-08-25 13:58:55 -0300641 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300642 case V4L2_PIX_FMT_YUV422P:
643 memcpy(vbuf, tmpbuf,
sensoray-dev340a30c2014-02-12 17:25:45 -0300644 vc->width * vc->height * 2);
Dean Anderson38f993a2008-06-26 23:15:51 -0300645 break;
646 default:
sensoray-devf5402002014-01-29 15:24:07 -0300647 pr_info("s2255: unknown format?\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300648 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300649 vc->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300650 } else {
sensoray-devf5402002014-01-29 15:24:07 -0300651 pr_err("s2255: =======no frame\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300652 return;
Dean Anderson38f993a2008-06-26 23:15:51 -0300653 }
sensoray-devf5402002014-01-29 15:24:07 -0300654 dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n",
Dean Anderson38f993a2008-06-26 23:15:51 -0300655 (unsigned long)vbuf, pos);
Dean Anderson38f993a2008-06-26 23:15:51 -0300656}
657
658
659/* ------------------------------------------------------------------
660 Videobuf operations
661 ------------------------------------------------------------------*/
662
Hans Verkuildf9ecb02015-10-28 00:50:37 -0200663static int queue_setup(struct vb2_queue *vq,
sensoray-dev340a30c2014-02-12 17:25:45 -0300664 unsigned int *nbuffers, unsigned int *nplanes,
665 unsigned int sizes[], void *alloc_ctxs[])
Dean Anderson38f993a2008-06-26 23:15:51 -0300666{
sensoray-dev340a30c2014-02-12 17:25:45 -0300667 struct s2255_vc *vc = vb2_get_drv_priv(vq);
Dean Anderson9da62eb2014-02-05 14:58:06 -0300668 if (*nbuffers < S2255_MIN_BUFS)
669 *nbuffers = S2255_MIN_BUFS;
sensoray-dev340a30c2014-02-12 17:25:45 -0300670 *nplanes = 1;
671 sizes[0] = vc->width * vc->height * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300672 return 0;
673}
674
sensoray-dev340a30c2014-02-12 17:25:45 -0300675static int buffer_prepare(struct vb2_buffer *vb)
Dean Anderson38f993a2008-06-26 23:15:51 -0300676{
sensoray-dev340a30c2014-02-12 17:25:45 -0300677 struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
Junghak Sung2d700712015-09-22 10:30:30 -0300678 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
679 struct s2255_buffer *buf = container_of(vbuf, 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
Junghak Sung2d700712015-09-22 10:30:30 -0300701 vb2_set_plane_payload(&buf->vb.vb2_buf, 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{
Junghak Sung2d700712015-09-22 10:30:30 -0300707 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
708 struct s2255_buffer *buf = container_of(vbuf, struct s2255_buffer, vb);
sensoray-dev340a30c2014-02-12 17:25:45 -0300709 struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
710 unsigned long flags = 0;
Dean Anderson92cde472014-02-05 17:38:42 -0300711 dprintk(vc->dev, 1, "%s\n", __func__);
sensoray-dev340a30c2014-02-12 17:25:45 -0300712 spin_lock_irqsave(&vc->qlock, flags);
713 list_add_tail(&buf->list, &vc->buf_list);
714 spin_unlock_irqrestore(&vc->qlock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300715}
716
sensoray-dev340a30c2014-02-12 17:25:45 -0300717static int start_streaming(struct vb2_queue *vq, unsigned int count);
Hans Verkuile37559b2014-04-17 02:47:21 -0300718static void stop_streaming(struct vb2_queue *vq);
Dean Anderson38f993a2008-06-26 23:15:51 -0300719
sensoray-dev340a30c2014-02-12 17:25:45 -0300720static struct vb2_ops s2255_video_qops = {
721 .queue_setup = queue_setup,
Dean Anderson38f993a2008-06-26 23:15:51 -0300722 .buf_prepare = buffer_prepare,
723 .buf_queue = buffer_queue,
sensoray-dev340a30c2014-02-12 17:25:45 -0300724 .start_streaming = start_streaming,
725 .stop_streaming = stop_streaming,
726 .wait_prepare = vb2_ops_wait_prepare,
727 .wait_finish = vb2_ops_wait_finish,
Dean Anderson38f993a2008-06-26 23:15:51 -0300728};
729
Dean Anderson38f993a2008-06-26 23:15:51 -0300730static int vidioc_querycap(struct file *file, void *priv,
731 struct v4l2_capability *cap)
732{
sensoray-dev340a30c2014-02-12 17:25:45 -0300733 struct s2255_vc *vc = video_drvdata(file);
734 struct s2255_dev *dev = vc->dev;
Hans Verkuil39696002013-02-07 07:06:21 -0300735
Dean Anderson38f993a2008-06-26 23:15:51 -0300736 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
737 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300738 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
sensoray-dev340a30c2014-02-12 17:25:45 -0300739 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
740 V4L2_CAP_READWRITE;
Hans Verkuil39696002013-02-07 07:06:21 -0300741 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300742 return 0;
743}
744
745static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
746 struct v4l2_fmtdesc *f)
747{
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300748 int index = f->index;
Dean Anderson38f993a2008-06-26 23:15:51 -0300749
750 if (index >= ARRAY_SIZE(formats))
751 return -EINVAL;
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300752 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
753 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
754 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300755 strlcpy(f->description, formats[index].name, sizeof(f->description));
756 f->pixelformat = formats[index].fourcc;
757 return 0;
758}
759
760static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
761 struct v4l2_format *f)
762{
sensoray-dev340a30c2014-02-12 17:25:45 -0300763 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300764 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300765
Dean Anderson5e950fa2014-02-04 18:16:24 -0300766 f->fmt.pix.width = vc->width;
767 f->fmt.pix.height = vc->height;
Hans Verkuil92513612013-02-15 06:05:08 -0300768 if (f->fmt.pix.height >=
769 (is_ntsc ? NUM_LINES_1CIFS_NTSC : NUM_LINES_1CIFS_PAL) * 2)
770 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
771 else
772 f->fmt.pix.field = V4L2_FIELD_TOP;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300773 f->fmt.pix.pixelformat = vc->fmt->fourcc;
774 f->fmt.pix.bytesperline = f->fmt.pix.width * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300775 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300776 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
777 f->fmt.pix.priv = 0;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300778 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300779}
780
781static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
782 struct v4l2_format *f)
783{
784 const struct s2255_fmt *fmt;
785 enum v4l2_field field;
sensoray-dev340a30c2014-02-12 17:25:45 -0300786 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300787 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300788
789 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
790
791 if (fmt == NULL)
792 return -EINVAL;
793
794 field = f->fmt.pix.field;
Dean Anderson38f993a2008-06-26 23:15:51 -0300795
Dean Anderson92cde472014-02-05 17:38:42 -0300796 dprintk(vc->dev, 50, "%s NTSC: %d suggested width: %d, height: %d\n",
Dean Anderson85b85482010-04-08 23:51:17 -0300797 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300798 if (is_ntsc) {
799 /* NTSC */
800 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
801 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300802 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300803 } else {
804 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
Hans Verkuil92513612013-02-15 06:05:08 -0300805 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300806 }
807 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
808 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
809 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
810 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
811 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
812 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
813 else
814 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
815 } else {
816 /* PAL */
817 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
818 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300819 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300820 } else {
821 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300822 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300823 }
Hans Verkuil92513612013-02-15 06:05:08 -0300824 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300825 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300826 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300827 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300828 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300829 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300830 else
Dean Anderson38f993a2008-06-26 23:15:51 -0300831 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300832 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300833 f->fmt.pix.field = field;
834 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
835 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300836 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
837 f->fmt.pix.priv = 0;
Dean Anderson92cde472014-02-05 17:38:42 -0300838 dprintk(vc->dev, 50, "%s: set width %d height %d field %d\n", __func__,
Dean Anderson85b85482010-04-08 23:51:17 -0300839 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300840 return 0;
841}
842
843static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
844 struct v4l2_format *f)
845{
sensoray-dev340a30c2014-02-12 17:25:45 -0300846 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson38f993a2008-06-26 23:15:51 -0300847 const struct s2255_fmt *fmt;
sensoray-dev340a30c2014-02-12 17:25:45 -0300848 struct vb2_queue *q = &vc->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300849 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300850 int ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300851
sensoray-dev340a30c2014-02-12 17:25:45 -0300852 ret = vidioc_try_fmt_vid_cap(file, vc, f);
Dean Anderson38f993a2008-06-26 23:15:51 -0300853
854 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300855 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300856
857 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
858
859 if (fmt == NULL)
860 return -EINVAL;
861
sensoray-dev340a30c2014-02-12 17:25:45 -0300862 if (vb2_is_busy(q)) {
Dean Anderson92cde472014-02-05 17:38:42 -0300863 dprintk(vc->dev, 1, "queue busy\n");
sensoray-dev340a30c2014-02-12 17:25:45 -0300864 return -EBUSY;
Dean Anderson38f993a2008-06-26 23:15:51 -0300865 }
866
Dean Anderson5e950fa2014-02-04 18:16:24 -0300867 mode = vc->mode;
868 vc->fmt = fmt;
869 vc->width = f->fmt.pix.width;
870 vc->height = f->fmt.pix.height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300871 vc->field = f->fmt.pix.field;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300872 if (vc->width > norm_minw(vc)) {
873 if (vc->height > norm_minh(vc)) {
874 if (vc->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -0300875 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300876 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -0300877 else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300878 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -0300879 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300880 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300881
882 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300883 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300884 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300885 /* color mode */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300886 switch (vc->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300887 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300888 mode.color &= ~MASK_COLOR;
889 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -0300890 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300891 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300892 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300893 mode.color &= ~MASK_COLOR;
894 mode.color |= COLOR_JPG;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300895 mode.color |= (vc->jpegqual << 8);
Dean Anderson14d96262008-08-25 13:58:55 -0300896 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300897 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300898 mode.color &= ~MASK_COLOR;
899 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300900 break;
901 case V4L2_PIX_FMT_YUYV:
902 case V4L2_PIX_FMT_UYVY:
903 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300904 mode.color &= ~MASK_COLOR;
905 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -0300906 break;
907 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300908 if ((mode.color & MASK_COLOR) != (vc->mode.color & MASK_COLOR))
Dean Andersonfe85ce92010-06-01 19:12:07 -0300909 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300910 else if (mode.scale != vc->mode.scale)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300911 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300912 else if (mode.format != vc->mode.format)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300913 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300914 vc->mode = mode;
915 (void) s2255_set_mode(vc, &mode);
sensoray-dev340a30c2014-02-12 17:25:45 -0300916 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300917}
918
Dean Anderson38f993a2008-06-26 23:15:51 -0300919
Dean Anderson38f993a2008-06-26 23:15:51 -0300920/* write to the configuration pipe, synchronously */
921static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
922 int size)
923{
924 int pipe;
925 int done;
926 long retval = -1;
927 if (udev) {
928 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
929 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
930 }
931 return retval;
932}
933
934static u32 get_transfer_size(struct s2255_mode *mode)
935{
936 int linesPerFrame = LINE_SZ_DEF;
937 int pixelsPerLine = NUM_LINES_DEF;
938 u32 outImageSize;
939 u32 usbInSize;
940 unsigned int mask_mult;
941
942 if (mode == NULL)
943 return 0;
944
945 if (mode->format == FORMAT_NTSC) {
946 switch (mode->scale) {
947 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -0300948 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -0300949 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
950 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
951 break;
952 case SCALE_2CIFS:
953 linesPerFrame = NUM_LINES_2CIFS_NTSC;
954 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
955 break;
956 case SCALE_1CIFS:
957 linesPerFrame = NUM_LINES_1CIFS_NTSC;
958 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
959 break;
960 default:
961 break;
962 }
963 } else if (mode->format == FORMAT_PAL) {
964 switch (mode->scale) {
965 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -0300966 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -0300967 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
968 pixelsPerLine = LINE_SZ_4CIFS_PAL;
969 break;
970 case SCALE_2CIFS:
971 linesPerFrame = NUM_LINES_2CIFS_PAL;
972 pixelsPerLine = LINE_SZ_2CIFS_PAL;
973 break;
974 case SCALE_1CIFS:
975 linesPerFrame = NUM_LINES_1CIFS_PAL;
976 pixelsPerLine = LINE_SZ_1CIFS_PAL;
977 break;
978 default:
979 break;
980 }
981 }
982 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -0300983 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300984 /* 2 bytes/pixel if not monochrome */
985 outImageSize *= 2;
986 }
987
988 /* total bytes to send including prefix and 4K padding;
989 must be a multiple of USB_READ_SIZE */
990 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
991 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
992 /* if size not a multiple of USB_READ_SIZE */
993 if (usbInSize & ~mask_mult)
994 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
995 return usbInSize;
996}
997
Dean Anderson85b85482010-04-08 23:51:17 -0300998static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -0300999{
1000 struct device *dev = &sdev->udev->dev;
1001 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001002 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1003 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001004 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001005 dev_info(dev, "------------------------------------------------\n");
1006}
1007
1008/*
1009 * set mode is the function which controls the DSP.
1010 * the restart parameter in struct s2255_mode should be set whenever
1011 * the image size could change via color format, video system or image
1012 * size.
1013 * When the restart parameter is set, we sleep for ONE frame to allow the
1014 * DSP time to get the new frame
1015 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001016static int s2255_set_mode(struct s2255_vc *vc,
Dean Anderson38f993a2008-06-26 23:15:51 -03001017 struct s2255_mode *mode)
1018{
1019 int res;
Dean Anderson38f993a2008-06-26 23:15:51 -03001020 unsigned long chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001021 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001022 int i;
Dean Anderson47d8c882014-02-05 15:43:51 -03001023 __le32 *buffer = dev->cmdbuf;
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001024
Dean Anderson47d8c882014-02-05 15:43:51 -03001025 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001026 chn_rev = G_chnmap[vc->idx];
1027 dprintk(dev, 3, "%s channel: %d\n", __func__, vc->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001028 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001029 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1030 mode->color &= ~MASK_COLOR;
1031 mode->color |= COLOR_JPG;
1032 mode->color &= ~MASK_JPG_QUALITY;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001033 mode->color |= (vc->jpegqual << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001034 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001035 /* save the mode */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001036 vc->mode = *mode;
1037 vc->req_image_size = get_transfer_size(mode);
1038 dprintk(dev, 1, "%s: reqsize %ld\n", __func__, vc->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001039 /* set the mode */
1040 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001041 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001042 buffer[2] = CMD_SET_MODE;
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001043 for (i = 0; i < sizeof(struct s2255_mode) / sizeof(u32); i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001044 buffer[3 + i] = cpu_to_le32(((u32 *)&vc->mode)[i]);
1045 vc->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001046 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1047 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001048 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001049 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001050 if (mode->restart) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001051 wait_event_timeout(vc->wait_setmode,
1052 (vc->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001053 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001054 if (vc->setmode_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001055 dprintk(dev, 0, "s2255: no set mode response\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001056 res = -EFAULT;
1057 }
1058 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001059 /* clear the restart flag */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001060 vc->mode.restart = 0;
1061 dprintk(dev, 1, "%s chn %d, result: %d\n", __func__, vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03001062 mutex_unlock(&dev->cmdlock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001063 return res;
1064}
1065
Dean Anderson5e950fa2014-02-04 18:16:24 -03001066static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001067{
1068 int res;
Dean Anderson4de39f52010-03-03 19:39:19 -03001069 u32 chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001070 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03001071 __le32 *buffer = dev->cmdbuf;
1072
1073 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001074 chn_rev = G_chnmap[vc->idx];
1075 dprintk(dev, 4, "%s chan %d\n", __func__, vc->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001076 /* form the get vid status command */
1077 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001078 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001079 buffer[2] = CMD_STATUS;
1080 *pstatus = 0;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001081 vc->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001082 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001083 wait_event_timeout(vc->wait_vidstatus,
1084 (vc->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001085 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001086 if (vc->vidstatus_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001087 dprintk(dev, 0, "s2255: no vidstatus response\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001088 res = -EFAULT;
1089 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001090 *pstatus = vc->vidstatus;
sensoray-devf5402002014-01-29 15:24:07 -03001091 dprintk(dev, 4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson47d8c882014-02-05 15:43:51 -03001092 mutex_unlock(&dev->cmdlock);
Dean Anderson4de39f52010-03-03 19:39:19 -03001093 return res;
1094}
1095
sensoray-dev340a30c2014-02-12 17:25:45 -03001096static int start_streaming(struct vb2_queue *vq, unsigned int count)
Dean Anderson38f993a2008-06-26 23:15:51 -03001097{
sensoray-dev340a30c2014-02-12 17:25:45 -03001098 struct s2255_vc *vc = vb2_get_drv_priv(vq);
Dean Anderson38f993a2008-06-26 23:15:51 -03001099 int j;
Dean Anderson92cde472014-02-05 17:38:42 -03001100
Dean Anderson5e950fa2014-02-04 18:16:24 -03001101 vc->last_frame = -1;
1102 vc->bad_payload = 0;
1103 vc->cur_frame = 0;
1104 vc->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001105 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001106 vc->buffer.frame[j].ulState = S2255_READ_IDLE;
1107 vc->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001108 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001109 return s2255_start_acquire(vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03001110}
1111
sensoray-dev340a30c2014-02-12 17:25:45 -03001112/* abort streaming and wait for last buffer */
Hans Verkuile37559b2014-04-17 02:47:21 -03001113static void stop_streaming(struct vb2_queue *vq)
Dean Anderson38f993a2008-06-26 23:15:51 -03001114{
sensoray-dev340a30c2014-02-12 17:25:45 -03001115 struct s2255_vc *vc = vb2_get_drv_priv(vq);
1116 struct s2255_buffer *buf, *node;
1117 unsigned long flags;
1118 (void) s2255_stop_acquire(vc);
1119 spin_lock_irqsave(&vc->qlock, flags);
1120 list_for_each_entry_safe(buf, node, &vc->buf_list, list) {
1121 list_del(&buf->list);
Junghak Sung2d700712015-09-22 10:30:30 -03001122 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
sensoray-dev340a30c2014-02-12 17:25:45 -03001123 dprintk(vc->dev, 2, "[%p/%d] done\n",
Junghak Sung2d700712015-09-22 10:30:30 -03001124 buf, buf->vb.vb2_buf.index);
sensoray-dev340a30c2014-02-12 17:25:45 -03001125 }
1126 spin_unlock_irqrestore(&vc->qlock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -03001127}
1128
Hans Verkuil314527a2013-03-15 06:10:40 -03001129static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i)
Dean Anderson38f993a2008-06-26 23:15:51 -03001130{
sensoray-dev340a30c2014-02-12 17:25:45 -03001131 struct s2255_vc *vc = video_drvdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001132 struct s2255_mode mode;
sensoray-dev340a30c2014-02-12 17:25:45 -03001133 struct vb2_queue *q = &vc->vb_vidq;
Hans Verkuil469af772013-02-15 06:12:58 -03001134
sensoray-dev340a30c2014-02-12 17:25:45 -03001135 /*
1136 * Changing the standard implies a format change, which is not allowed
1137 * while buffers for use with streaming have already been allocated.
1138 */
1139 if (vb2_is_busy(q))
1140 return -EBUSY;
1141
Dean Anderson92cde472014-02-05 17:38:42 -03001142 mode = vc->mode;
Hans Verkuil314527a2013-03-15 06:10:40 -03001143 if (i & V4L2_STD_525_60) {
Dean Anderson92cde472014-02-05 17:38:42 -03001144 dprintk(vc->dev, 4, "%s 60 Hz\n", __func__);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001145 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001146 if (mode.format != FORMAT_NTSC) {
1147 mode.restart = 1;
1148 mode.format = FORMAT_NTSC;
1149 mode.fdec = FDEC_1;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001150 vc->width = LINE_SZ_4CIFS_NTSC;
1151 vc->height = NUM_LINES_4CIFS_NTSC * 2;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001152 }
Hans Verkuil314527a2013-03-15 06:10:40 -03001153 } else if (i & V4L2_STD_625_50) {
Dean Anderson92cde472014-02-05 17:38:42 -03001154 dprintk(vc->dev, 4, "%s 50 Hz\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001155 if (mode.format != FORMAT_PAL) {
1156 mode.restart = 1;
1157 mode.format = FORMAT_PAL;
1158 mode.fdec = FDEC_1;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001159 vc->width = LINE_SZ_4CIFS_PAL;
1160 vc->height = NUM_LINES_4CIFS_PAL * 2;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001161 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001162 } else
1163 return -EINVAL;
Dean Anderson92cde472014-02-05 17:38:42 -03001164 vc->std = i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001165 if (mode.restart)
Dean Anderson92cde472014-02-05 17:38:42 -03001166 s2255_set_mode(vc, &mode);
sensoray-dev340a30c2014-02-12 17:25:45 -03001167 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001168}
1169
Hans Verkuil469af772013-02-15 06:12:58 -03001170static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *i)
1171{
sensoray-dev340a30c2014-02-12 17:25:45 -03001172 struct s2255_vc *vc = video_drvdata(file);
Hans Verkuil469af772013-02-15 06:12:58 -03001173
Dean Anderson92cde472014-02-05 17:38:42 -03001174 *i = vc->std;
Hans Verkuil469af772013-02-15 06:12:58 -03001175 return 0;
1176}
1177
Dean Anderson38f993a2008-06-26 23:15:51 -03001178/* Sensoray 2255 is a multiple channel capture device.
1179 It does not have a "crossbar" of inputs.
1180 We use one V4L device per channel. The user must
1181 be aware that certain combinations are not allowed.
1182 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1183 at once in color(you can do full fps on 4 channels with greyscale.
1184*/
1185static int vidioc_enum_input(struct file *file, void *priv,
1186 struct v4l2_input *inp)
1187{
sensoray-dev340a30c2014-02-12 17:25:45 -03001188 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson92cde472014-02-05 17:38:42 -03001189 struct s2255_dev *dev = vc->dev;
Dean Anderson4de39f52010-03-03 19:39:19 -03001190 u32 status = 0;
Dean Anderson92cde472014-02-05 17:38:42 -03001191
Dean Anderson38f993a2008-06-26 23:15:51 -03001192 if (inp->index != 0)
1193 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001194 inp->type = V4L2_INPUT_TYPE_CAMERA;
1195 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001196 inp->status = 0;
1197 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1198 int rc;
Dean Anderson92cde472014-02-05 17:38:42 -03001199 rc = s2255_cmd_status(vc, &status);
sensoray-devf5402002014-01-29 15:24:07 -03001200 dprintk(dev, 4, "s2255_cmd_status rc: %d status %x\n",
1201 rc, status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001202 if (rc == 0)
1203 inp->status = (status & 0x01) ? 0
1204 : V4L2_IN_ST_NO_SIGNAL;
1205 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001206 switch (dev->pid) {
1207 case 0x2255:
1208 default:
1209 strlcpy(inp->name, "Composite", sizeof(inp->name));
1210 break;
1211 case 0x2257:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001212 strlcpy(inp->name, (vc->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001213 sizeof(inp->name));
1214 break;
1215 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001216 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001217}
1218
1219static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1220{
1221 *i = 0;
1222 return 0;
1223}
1224static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1225{
1226 if (i > 0)
1227 return -EINVAL;
1228 return 0;
1229}
1230
Hans Verkuil192f1e72013-02-15 05:51:21 -03001231static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
Dean Anderson38f993a2008-06-26 23:15:51 -03001232{
Dean Anderson5e950fa2014-02-04 18:16:24 -03001233 struct s2255_vc *vc =
1234 container_of(ctrl->handler, struct s2255_vc, hdl);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001235 struct s2255_mode mode;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001236 mode = vc->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001237 /* update the mode to the corresponding value */
1238 switch (ctrl->id) {
1239 case V4L2_CID_BRIGHTNESS:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001240 mode.bright = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001241 break;
1242 case V4L2_CID_CONTRAST:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001243 mode.contrast = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001244 break;
1245 case V4L2_CID_HUE:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001246 mode.hue = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001247 break;
1248 case V4L2_CID_SATURATION:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001249 mode.saturation = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001250 break;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001251 case V4L2_CID_S2255_COLORFILTER:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001252 mode.color &= ~MASK_INPUT_TYPE;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001253 mode.color |= !ctrl->val << 16;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001254 break;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001255 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001256 vc->jpegqual = ctrl->val;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001257 return 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001258 default:
1259 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001260 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001261 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001262 /* set mode here. Note: stream does not need restarted.
1263 some V4L programs restart stream unnecessarily
1264 after a s_crtl.
1265 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001266 s2255_set_mode(vc, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001267 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001268}
1269
Dean Anderson22b88d42008-08-29 15:33:19 -03001270static int vidioc_g_jpegcomp(struct file *file, void *priv,
1271 struct v4l2_jpegcompression *jc)
1272{
sensoray-dev340a30c2014-02-12 17:25:45 -03001273 struct s2255_vc *vc = video_drvdata(file);
Hans Verkuil7041dec2013-02-15 05:53:45 -03001274
1275 memset(jc, 0, sizeof(*jc));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001276 jc->quality = vc->jpegqual;
Dean Anderson92cde472014-02-05 17:38:42 -03001277 dprintk(vc->dev, 2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001278 return 0;
1279}
1280
1281static int vidioc_s_jpegcomp(struct file *file, void *priv,
Hans Verkuild88aab52012-09-17 05:05:25 -03001282 const struct v4l2_jpegcompression *jc)
Dean Anderson22b88d42008-08-29 15:33:19 -03001283{
sensoray-dev340a30c2014-02-12 17:25:45 -03001284 struct s2255_vc *vc = video_drvdata(file);
1285
Dean Anderson22b88d42008-08-29 15:33:19 -03001286 if (jc->quality < 0 || jc->quality > 100)
1287 return -EINVAL;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001288 v4l2_ctrl_s_ctrl(vc->jpegqual_ctrl, jc->quality);
Dean Anderson92cde472014-02-05 17:38:42 -03001289 dprintk(vc->dev, 2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001290 return 0;
1291}
Dean Anderson7d853532009-05-15 14:32:04 -03001292
1293static int vidioc_g_parm(struct file *file, void *priv,
1294 struct v4l2_streamparm *sp)
1295{
Dean Andersone6b44bc2010-03-08 20:04:48 -03001296 __u32 def_num, def_dem;
sensoray-dev340a30c2014-02-12 17:25:45 -03001297 struct s2255_vc *vc = video_drvdata(file);
1298
Dean Anderson7d853532009-05-15 14:32:04 -03001299 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1300 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001301 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001302 sp->parm.capture.capturemode = vc->cap_parm.capturemode;
sensoray-dev340a30c2014-02-12 17:25:45 -03001303 sp->parm.capture.readbuffers = S2255_MIN_BUFS;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001304 def_num = (vc->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1305 def_dem = (vc->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001306 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001307 switch (vc->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001308 default:
1309 case FDEC_1:
1310 sp->parm.capture.timeperframe.numerator = def_num;
1311 break;
1312 case FDEC_2:
1313 sp->parm.capture.timeperframe.numerator = def_num * 2;
1314 break;
1315 case FDEC_3:
1316 sp->parm.capture.timeperframe.numerator = def_num * 3;
1317 break;
1318 case FDEC_5:
1319 sp->parm.capture.timeperframe.numerator = def_num * 5;
1320 break;
1321 }
Dean Anderson92cde472014-02-05 17:38:42 -03001322 dprintk(vc->dev, 4, "%s capture mode, %d timeperframe %d/%d\n",
sensoray-devf5402002014-01-29 15:24:07 -03001323 __func__,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001324 sp->parm.capture.capturemode,
1325 sp->parm.capture.timeperframe.numerator,
1326 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001327 return 0;
1328}
1329
1330static int vidioc_s_parm(struct file *file, void *priv,
1331 struct v4l2_streamparm *sp)
1332{
sensoray-dev340a30c2014-02-12 17:25:45 -03001333 struct s2255_vc *vc = video_drvdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001334 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001335 int fdec = FDEC_1;
1336 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001337 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1338 return -EINVAL;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001339 mode = vc->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001340 /* high quality capture mode requires a stream restart */
sensoray-dev340a30c2014-02-12 17:25:45 -03001341 if ((vc->cap_parm.capturemode != sp->parm.capture.capturemode)
1342 && vb2_is_streaming(&vc->vb_vidq))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001343 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001344 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1345 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001346 if (def_dem != sp->parm.capture.timeperframe.denominator)
1347 sp->parm.capture.timeperframe.numerator = def_num;
1348 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1349 sp->parm.capture.timeperframe.numerator = def_num;
1350 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1351 sp->parm.capture.timeperframe.numerator = def_num * 2;
1352 fdec = FDEC_2;
1353 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1354 sp->parm.capture.timeperframe.numerator = def_num * 3;
1355 fdec = FDEC_3;
1356 } else {
1357 sp->parm.capture.timeperframe.numerator = def_num * 5;
1358 fdec = FDEC_5;
1359 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001360 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001361 sp->parm.capture.timeperframe.denominator = def_dem;
sensoray-dev340a30c2014-02-12 17:25:45 -03001362 sp->parm.capture.readbuffers = S2255_MIN_BUFS;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001363 s2255_set_mode(vc, &mode);
Dean Anderson92cde472014-02-05 17:38:42 -03001364 dprintk(vc->dev, 4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
Dean Andersone6b44bc2010-03-08 20:04:48 -03001365 __func__,
1366 sp->parm.capture.capturemode,
1367 sp->parm.capture.timeperframe.numerator,
1368 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001369 return 0;
1370}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001371
Hans Verkuil05e5d442013-02-15 06:09:18 -03001372#define NUM_SIZE_ENUMS 3
1373static const struct v4l2_frmsize_discrete ntsc_sizes[] = {
1374 { 640, 480 },
1375 { 640, 240 },
1376 { 320, 240 },
1377};
1378static const struct v4l2_frmsize_discrete pal_sizes[] = {
1379 { 704, 576 },
1380 { 704, 288 },
1381 { 352, 288 },
1382};
1383
1384static int vidioc_enum_framesizes(struct file *file, void *priv,
1385 struct v4l2_frmsizeenum *fe)
1386{
sensoray-dev340a30c2014-02-12 17:25:45 -03001387 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001388 int is_ntsc = vc->std & V4L2_STD_525_60;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001389 const struct s2255_fmt *fmt;
1390
1391 if (fe->index >= NUM_SIZE_ENUMS)
1392 return -EINVAL;
1393
1394 fmt = format_by_fourcc(fe->pixel_format);
1395 if (fmt == NULL)
1396 return -EINVAL;
1397 fe->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1398 fe->discrete = is_ntsc ? ntsc_sizes[fe->index] : pal_sizes[fe->index];
1399 return 0;
1400}
1401
Dean Andersone6b44bc2010-03-08 20:04:48 -03001402static int vidioc_enum_frameintervals(struct file *file, void *priv,
1403 struct v4l2_frmivalenum *fe)
1404{
sensoray-dev340a30c2014-02-12 17:25:45 -03001405 struct s2255_vc *vc = video_drvdata(file);
Hans Verkuil05e5d442013-02-15 06:09:18 -03001406 const struct s2255_fmt *fmt;
1407 const struct v4l2_frmsize_discrete *sizes;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001408 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001409#define NUM_FRAME_ENUMS 4
1410 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
Hans Verkuil05e5d442013-02-15 06:09:18 -03001411 int i;
1412
Mauro Carvalho Chehab199ab8f2012-10-27 16:29:34 -03001413 if (fe->index >= NUM_FRAME_ENUMS)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001414 return -EINVAL;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001415
1416 fmt = format_by_fourcc(fe->pixel_format);
1417 if (fmt == NULL)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001418 return -EINVAL;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001419
1420 sizes = is_ntsc ? ntsc_sizes : pal_sizes;
1421 for (i = 0; i < NUM_SIZE_ENUMS; i++, sizes++)
1422 if (fe->width == sizes->width &&
1423 fe->height == sizes->height)
1424 break;
1425 if (i == NUM_SIZE_ENUMS)
1426 return -EINVAL;
1427
Dean Andersone6b44bc2010-03-08 20:04:48 -03001428 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1429 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1430 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
Dean Anderson92cde472014-02-05 17:38:42 -03001431 dprintk(vc->dev, 4, "%s discrete %d/%d\n", __func__,
sensoray-devf5402002014-01-29 15:24:07 -03001432 fe->discrete.numerator,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001433 fe->discrete.denominator);
1434 return 0;
1435}
1436
sensoray-dev340a30c2014-02-12 17:25:45 -03001437static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001438{
Dean Anderson5e950fa2014-02-04 18:16:24 -03001439 struct s2255_vc *vc = video_drvdata(file);
sensoray-dev340a30c2014-02-12 17:25:45 -03001440 struct s2255_dev *dev = vc->dev;
Dean Anderson14d96262008-08-25 13:58:55 -03001441 int state;
sensoray-dev340a30c2014-02-12 17:25:45 -03001442 int rc = 0;
1443
1444 rc = v4l2_fh_open(file);
1445 if (rc != 0)
1446 return rc;
1447
1448 dprintk(dev, 1, "s2255: %s\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001449 state = atomic_read(&dev->fw_data->fw_state);
1450 switch (state) {
1451 case S2255_FW_DISCONNECTING:
Dean Andersonff7e22d2010-04-08 23:38:07 -03001452 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001453 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001454 s2255_dev_err(&dev->udev->dev,
1455 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001456 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001457 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001458 ((atomic_read(&dev->fw_data->fw_state)
1459 == S2255_FW_SUCCESS) ||
1460 (atomic_read(&dev->fw_data->fw_state)
1461 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001462 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001463 /* state may have changed, re-read */
1464 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001465 break;
1466 case S2255_FW_NOTLOADED:
1467 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001468 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1469 driver loaded and then device immediately opened */
sensoray-devf5402002014-01-29 15:24:07 -03001470 pr_info("%s waiting for firmware load\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001471 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001472 ((atomic_read(&dev->fw_data->fw_state)
1473 == S2255_FW_SUCCESS) ||
1474 (atomic_read(&dev->fw_data->fw_state)
1475 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001476 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001477 /* state may have changed, re-read */
1478 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001479 break;
1480 case S2255_FW_SUCCESS:
1481 default:
1482 break;
1483 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001484 /* state may have changed in above switch statement */
1485 switch (state) {
1486 case S2255_FW_SUCCESS:
1487 break;
1488 case S2255_FW_FAILED:
sensoray-devf5402002014-01-29 15:24:07 -03001489 pr_info("2255 firmware load failed.\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03001490 return -ENODEV;
1491 case S2255_FW_DISCONNECTING:
sensoray-devf5402002014-01-29 15:24:07 -03001492 pr_info("%s: disconnecting\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001493 return -ENODEV;
1494 case S2255_FW_LOADED_DSPWAIT:
1495 case S2255_FW_NOTLOADED:
sensoray-devf5402002014-01-29 15:24:07 -03001496 pr_info("%s: firmware not loaded, please retry\n",
1497 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001498 /*
1499 * Timeout on firmware load means device unusable.
1500 * Set firmware failure state.
1501 * On next s2255_open the firmware will be reloaded.
1502 */
1503 atomic_set(&dev->fw_data->fw_state,
1504 S2255_FW_FAILED);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001505 return -EAGAIN;
1506 default:
sensoray-devf5402002014-01-29 15:24:07 -03001507 pr_info("%s: unknown state\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001508 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001509 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001510 if (!vc->configured) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001511 /* configure channel to default state */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001512 vc->fmt = &formats[0];
1513 s2255_set_mode(vc, &vc->mode);
1514 vc->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001515 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001516 return 0;
1517}
1518
Dean Andersond62e85a2010-04-09 19:54:26 -03001519static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001520{
sensoray-devf5402002014-01-29 15:24:07 -03001521 dprintk(dev, 1, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001522 /* board shutdown stops the read pipe if it is running */
1523 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001524 /* make sure firmware still not trying to load */
Kirill Tkhai9f6be2b2014-04-17 17:47:04 -03001525 del_timer_sync(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001526 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001527 usb_kill_urb(dev->fw_data->fw_urb);
1528 usb_free_urb(dev->fw_data->fw_urb);
1529 dev->fw_data->fw_urb = NULL;
1530 }
Jesper Juhl3fc82fa2012-04-09 16:50:04 -03001531 release_firmware(dev->fw_data->fw);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001532 kfree(dev->fw_data->pfw_data);
1533 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001534 /* reset the DSP so firmware can be reloaded next time */
1535 s2255_reset_dsppower(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001536 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001537 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001538 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03001539 kfree(dev->cmdbuf);
Dean Andersonb7732a32009-03-30 11:59:56 -03001540 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001541}
1542
Hans Verkuilbec43662008-12-30 06:58:20 -03001543static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001544 .owner = THIS_MODULE,
1545 .open = s2255_open,
sensoray-dev340a30c2014-02-12 17:25:45 -03001546 .release = vb2_fop_release,
1547 .poll = vb2_fop_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001548 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
sensoray-dev340a30c2014-02-12 17:25:45 -03001549 .mmap = vb2_fop_mmap,
1550 .read = vb2_fop_read,
Dean Anderson38f993a2008-06-26 23:15:51 -03001551};
1552
Hans Verkuila3998102008-07-21 02:57:38 -03001553static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001554 .vidioc_querycap = vidioc_querycap,
1555 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1556 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1557 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1558 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
sensoray-dev340a30c2014-02-12 17:25:45 -03001559 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1560 .vidioc_querybuf = vb2_ioctl_querybuf,
1561 .vidioc_qbuf = vb2_ioctl_qbuf,
1562 .vidioc_dqbuf = vb2_ioctl_dqbuf,
Dean Anderson38f993a2008-06-26 23:15:51 -03001563 .vidioc_s_std = vidioc_s_std,
Hans Verkuil469af772013-02-15 06:12:58 -03001564 .vidioc_g_std = vidioc_g_std,
Dean Anderson38f993a2008-06-26 23:15:51 -03001565 .vidioc_enum_input = vidioc_enum_input,
1566 .vidioc_g_input = vidioc_g_input,
1567 .vidioc_s_input = vidioc_s_input,
sensoray-dev340a30c2014-02-12 17:25:45 -03001568 .vidioc_streamon = vb2_ioctl_streamon,
1569 .vidioc_streamoff = vb2_ioctl_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001570 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1571 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001572 .vidioc_s_parm = vidioc_s_parm,
1573 .vidioc_g_parm = vidioc_g_parm,
Hans Verkuil05e5d442013-02-15 06:09:18 -03001574 .vidioc_enum_framesizes = vidioc_enum_framesizes,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001575 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuil44d06d82013-02-15 05:59:00 -03001576 .vidioc_log_status = v4l2_ctrl_log_status,
1577 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1578 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001579};
1580
Dean Andersonff7e22d2010-04-08 23:38:07 -03001581static void s2255_video_device_release(struct video_device *vdev)
1582{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001583 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001584 struct s2255_vc *vc =
1585 container_of(vdev, struct s2255_vc, vdev);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001586
sensoray-devf5402002014-01-29 15:24:07 -03001587 dprintk(dev, 4, "%s, chnls: %d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001588 atomic_read(&dev->num_channels));
Hans Verkuil192f1e72013-02-15 05:51:21 -03001589
Dean Anderson5e950fa2014-02-04 18:16:24 -03001590 v4l2_ctrl_handler_free(&vc->hdl);
sensoray-devf5402002014-01-29 15:24:07 -03001591
Dean Andersonfe85ce92010-06-01 19:12:07 -03001592 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001593 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001594 return;
1595}
1596
Hans Verkuila3998102008-07-21 02:57:38 -03001597static struct video_device template = {
1598 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001599 .fops = &s2255_fops_v4l,
1600 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001601 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001602 .tvnorms = S2255_NORMS,
Dean Anderson38f993a2008-06-26 23:15:51 -03001603};
1604
Hans Verkuil192f1e72013-02-15 05:51:21 -03001605static const struct v4l2_ctrl_ops s2255_ctrl_ops = {
1606 .s_ctrl = s2255_s_ctrl,
1607};
1608
1609static const struct v4l2_ctrl_config color_filter_ctrl = {
1610 .ops = &s2255_ctrl_ops,
1611 .name = "Color Filter",
1612 .id = V4L2_CID_S2255_COLORFILTER,
1613 .type = V4L2_CTRL_TYPE_BOOLEAN,
1614 .max = 1,
1615 .step = 1,
1616 .def = 1,
1617};
1618
Dean Anderson38f993a2008-06-26 23:15:51 -03001619static int s2255_probe_v4l(struct s2255_dev *dev)
1620{
1621 int ret;
1622 int i;
1623 int cur_nr = video_nr;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001624 struct s2255_vc *vc;
sensoray-dev340a30c2014-02-12 17:25:45 -03001625 struct vb2_queue *q;
1626
Dean Anderson65c6edb2010-04-20 17:21:32 -03001627 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1628 if (ret)
1629 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001630 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001631 /* register 4 video devices */
1632 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001633 vc = &dev->vc[i];
1634 INIT_LIST_HEAD(&vc->buf_list);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001635
Dean Anderson5e950fa2014-02-04 18:16:24 -03001636 v4l2_ctrl_handler_init(&vc->hdl, 6);
1637 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001638 V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001639 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001640 V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001641 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001642 V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001643 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001644 V4L2_CID_HUE, 0, 255, 1, DEF_HUE);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001645 vc->jpegqual_ctrl = v4l2_ctrl_new_std(&vc->hdl,
Hans Verkuil7041dec2013-02-15 05:53:45 -03001646 &s2255_ctrl_ops,
1647 V4L2_CID_JPEG_COMPRESSION_QUALITY,
1648 0, 100, 1, S2255_DEF_JPEG_QUAL);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001649 if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER &&
Dean Anderson5e950fa2014-02-04 18:16:24 -03001650 (dev->pid != 0x2257 || vc->idx <= 1))
1651 v4l2_ctrl_new_custom(&vc->hdl, &color_filter_ctrl,
sensoray-devf5402002014-01-29 15:24:07 -03001652 NULL);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001653 if (vc->hdl.error) {
1654 ret = vc->hdl.error;
1655 v4l2_ctrl_handler_free(&vc->hdl);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001656 dev_err(&dev->udev->dev, "couldn't register control\n");
1657 break;
1658 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001659 q = &vc->vb_vidq;
1660 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1661 q->io_modes = VB2_MMAP | VB2_READ | VB2_USERPTR;
1662 q->drv_priv = vc;
1663 q->lock = &vc->vb_lock;
1664 q->buf_struct_size = sizeof(struct s2255_buffer);
1665 q->mem_ops = &vb2_vmalloc_memops;
1666 q->ops = &s2255_video_qops;
Sakari Ailusade48682014-02-25 19:12:19 -03001667 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
sensoray-dev340a30c2014-02-12 17:25:45 -03001668 ret = vb2_queue_init(q);
1669 if (ret != 0) {
1670 dev_err(&dev->udev->dev,
1671 "%s vb2_queue_init 0x%x\n", __func__, ret);
1672 break;
1673 }
1674 /* register video devices */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001675 vc->vdev = template;
sensoray-dev340a30c2014-02-12 17:25:45 -03001676 vc->vdev.queue = q;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001677 vc->vdev.ctrl_handler = &vc->hdl;
1678 vc->vdev.lock = &dev->lock;
1679 vc->vdev.v4l2_dev = &dev->v4l2_dev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001680 video_set_drvdata(&vc->vdev, vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03001681 if (video_nr == -1)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001682 ret = video_register_device(&vc->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001683 VFL_TYPE_GRABBER,
1684 video_nr);
1685 else
Dean Anderson5e950fa2014-02-04 18:16:24 -03001686 ret = video_register_device(&vc->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001687 VFL_TYPE_GRABBER,
1688 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001689
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001690 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001691 dev_err(&dev->udev->dev,
1692 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001693 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001694 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001695 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001696 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Anderson5e950fa2014-02-04 18:16:24 -03001697 video_device_node_name(&vc->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001698
Dean Anderson38f993a2008-06-26 23:15:51 -03001699 }
sensoray-devf5402002014-01-29 15:24:07 -03001700 pr_info("Sensoray 2255 V4L driver Revision: %s\n",
1701 S2255_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001702 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001703 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001704 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001705 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001706 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001707 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
sensoray-devf5402002014-01-29 15:24:07 -03001708 pr_warn("s2255: Not all channels available.\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001709 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001710}
1711
Dean Anderson38f993a2008-06-26 23:15:51 -03001712/* this function moves the usb stream read pipe data
1713 * into the system buffers.
1714 * returns 0 on success, EAGAIN if more data to process( call this
1715 * function again).
1716 *
1717 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001718 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001719 * bytes 4-7: channel: 0-3
1720 * bytes 8-11: payload size: size of the frame
1721 * bytes 12-payloadsize+12: frame data
1722 */
1723static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1724{
Dean Anderson38f993a2008-06-26 23:15:51 -03001725 char *pdest;
1726 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001727 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001728 char *psrc;
1729 unsigned long copy_size;
1730 unsigned long size;
1731 s32 idx = -1;
1732 struct s2255_framei *frm;
1733 unsigned char *pdata;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001734 struct s2255_vc *vc;
sensoray-devf5402002014-01-29 15:24:07 -03001735 dprintk(dev, 100, "buffer to user\n");
Dean Anderson5e950fa2014-02-04 18:16:24 -03001736 vc = &dev->vc[dev->cc];
1737 idx = vc->cur_frame;
1738 frm = &vc->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001739 if (frm->ulState == S2255_READ_IDLE) {
1740 int jj;
1741 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03001742 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03001743 int payload;
1744 /* search for marker codes */
1745 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03001746 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03001747 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03001748 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03001749 case S2255_MARKER_FRAME:
sensoray-devf5402002014-01-29 15:24:07 -03001750 dprintk(dev, 4, "marker @ offset: %d [%x %x]\n",
1751 jj, pdata[0], pdata[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001752 offset = jj + PREFIX_SIZE;
1753 bframe = 1;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001754 cc = le32_to_cpu(pdword[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001755 if (cc >= MAX_CHANNELS) {
sensoray-devf5402002014-01-29 15:24:07 -03001756 dprintk(dev, 0,
1757 "bad channel\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001758 return -EINVAL;
1759 }
1760 /* reverse it */
1761 dev->cc = G_chnmap[cc];
Dean Anderson5e950fa2014-02-04 18:16:24 -03001762 vc = &dev->vc[dev->cc];
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001763 payload = le32_to_cpu(pdword[3]);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001764 if (payload > vc->req_image_size) {
1765 vc->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03001766 /* discard the bad frame */
1767 return -EINVAL;
1768 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001769 vc->pkt_size = payload;
1770 vc->jpg_size = le32_to_cpu(pdword[4]);
Dean Anderson14d96262008-08-25 13:58:55 -03001771 break;
1772 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001773
Dean Anderson14d96262008-08-25 13:58:55 -03001774 pdata += DEF_USB_BLOCK;
1775 jj += DEF_USB_BLOCK;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001776 if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001777 break;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001778 cc = G_chnmap[le32_to_cpu(pdword[1])];
Roel Kluinf14a2972009-10-23 07:59:42 -03001779 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001780 break;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001781 vc = &dev->vc[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03001782 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03001783 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03001784 /* check if channel valid */
1785 /* set mode ready */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001786 vc->setmode_ready = 1;
1787 wake_up(&vc->wait_setmode);
sensoray-devf5402002014-01-29 15:24:07 -03001788 dprintk(dev, 5, "setmode rdy %d\n", cc);
Dean Anderson14d96262008-08-25 13:58:55 -03001789 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03001790 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03001791 dev->chn_ready |= (1 << cc);
1792 if ((dev->chn_ready & 0x0f) != 0x0f)
1793 break;
1794 /* all channels ready */
sensoray-devf5402002014-01-29 15:24:07 -03001795 pr_info("s2255: fw loaded\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001796 atomic_set(&dev->fw_data->fw_state,
1797 S2255_FW_SUCCESS);
1798 wake_up(&dev->fw_data->wait_fw);
1799 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03001800 case S2255_RESPONSE_STATUS:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001801 vc->vidstatus = le32_to_cpu(pdword[3]);
1802 vc->vidstatus_ready = 1;
1803 wake_up(&vc->wait_vidstatus);
sensoray-devf5402002014-01-29 15:24:07 -03001804 dprintk(dev, 5, "vstat %x chan %d\n",
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001805 le32_to_cpu(pdword[3]), cc);
Dean Anderson4de39f52010-03-03 19:39:19 -03001806 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001807 default:
sensoray-devf5402002014-01-29 15:24:07 -03001808 pr_info("s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001809 }
1810 default:
1811 pdata++;
1812 break;
1813 }
1814 if (bframe)
1815 break;
1816 } /* for */
1817 if (!bframe)
1818 return -EINVAL;
1819 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001820 vc = &dev->vc[dev->cc];
1821 idx = vc->cur_frame;
1822 frm = &vc->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001823 /* search done. now find out if should be acquiring on this channel */
sensoray-dev340a30c2014-02-12 17:25:45 -03001824 if (!vb2_is_streaming(&vc->vb_vidq)) {
Dean Anderson14d96262008-08-25 13:58:55 -03001825 /* we found a frame, but this channel is turned off */
1826 frm->ulState = S2255_READ_IDLE;
1827 return -EINVAL;
1828 }
1829
1830 if (frm->ulState == S2255_READ_IDLE) {
1831 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03001832 frm->cur_size = 0;
1833 }
1834
Dean Anderson14d96262008-08-25 13:58:55 -03001835 /* skip the marker 512 bytes (and offset if out of sync) */
1836 psrc = (u8 *)pipe_info->transfer_buffer + offset;
1837
Dean Anderson38f993a2008-06-26 23:15:51 -03001838
1839 if (frm->lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03001840 dprintk(dev, 1, "s2255 frame buffer == NULL.%p %p %d %d",
Dean Anderson38f993a2008-06-26 23:15:51 -03001841 frm, dev, dev->cc, idx);
1842 return -ENOMEM;
1843 }
1844
1845 pdest = frm->lpvbits + frm->cur_size;
1846
Dean Anderson14d96262008-08-25 13:58:55 -03001847 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03001848
Dean Anderson5e950fa2014-02-04 18:16:24 -03001849 size = vc->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001850
Dean Anderson14d96262008-08-25 13:58:55 -03001851 /* sanity check on pdest */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001852 if ((copy_size + frm->cur_size) < vc->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03001853 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001854
Dean Anderson38f993a2008-06-26 23:15:51 -03001855 frm->cur_size += copy_size;
sensoray-devf5402002014-01-29 15:24:07 -03001856 dprintk(dev, 4, "cur_size: %lu, size: %lu\n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001857
Dean Anderson14d96262008-08-25 13:58:55 -03001858 if (frm->cur_size >= size) {
sensoray-devf5402002014-01-29 15:24:07 -03001859 dprintk(dev, 2, "******[%d]Buffer[%d]full*******\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001860 dev->cc, idx);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001861 vc->last_frame = vc->cur_frame;
1862 vc->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03001863 /* end of system frame ring buffer, start at zero */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001864 if ((vc->cur_frame == SYS_FRAMES) ||
1865 (vc->cur_frame == vc->buffer.dwFrames))
1866 vc->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001867 /* frame ready */
sensoray-dev340a30c2014-02-12 17:25:45 -03001868 if (vb2_is_streaming(&vc->vb_vidq))
Dean Anderson5e950fa2014-02-04 18:16:24 -03001869 s2255_got_frame(vc, vc->jpg_size);
1870 vc->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03001871 frm->ulState = S2255_READ_IDLE;
1872 frm->cur_size = 0;
1873
Dean Anderson38f993a2008-06-26 23:15:51 -03001874 }
1875 /* done successfully */
1876 return 0;
1877}
1878
1879static void s2255_read_video_callback(struct s2255_dev *dev,
1880 struct s2255_pipeinfo *pipe_info)
1881{
1882 int res;
sensoray-devf5402002014-01-29 15:24:07 -03001883 dprintk(dev, 50, "callback read video\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001884
1885 if (dev->cc >= MAX_CHANNELS) {
1886 dev->cc = 0;
1887 dev_err(&dev->udev->dev, "invalid channel\n");
1888 return;
1889 }
1890 /* otherwise copy to the system buffers */
1891 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03001892 if (res != 0)
sensoray-devf5402002014-01-29 15:24:07 -03001893 dprintk(dev, 4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001894
sensoray-devf5402002014-01-29 15:24:07 -03001895 dprintk(dev, 50, "callback read video done\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001896 return;
1897}
1898
1899static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
1900 u16 Index, u16 Value, void *TransferBuffer,
1901 s32 TransferBufferLength, int bOut)
1902{
1903 int r;
1904 if (!bOut) {
1905 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
1906 Request,
1907 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
1908 USB_DIR_IN,
1909 Value, Index, TransferBuffer,
1910 TransferBufferLength, HZ * 5);
1911 } else {
1912 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
1913 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1914 Value, Index, TransferBuffer,
1915 TransferBufferLength, HZ * 5);
1916 }
1917 return r;
1918}
1919
1920/*
1921 * retrieve FX2 firmware version. future use.
1922 * @param dev pointer to device extension
1923 * @return -1 for fail, else returns firmware version as an int(16 bits)
1924 */
1925static int s2255_get_fx2fw(struct s2255_dev *dev)
1926{
1927 int fw;
1928 int ret;
1929 unsigned char transBuffer[64];
1930 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
1931 S2255_VR_IN);
1932 if (ret < 0)
sensoray-devf5402002014-01-29 15:24:07 -03001933 dprintk(dev, 2, "get fw error: %x\n", ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001934 fw = transBuffer[0] + (transBuffer[1] << 8);
sensoray-devf5402002014-01-29 15:24:07 -03001935 dprintk(dev, 2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
Dean Anderson38f993a2008-06-26 23:15:51 -03001936 return fw;
1937}
1938
1939/*
1940 * Create the system ring buffer to copy frames into from the
1941 * usb read pipe.
1942 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001943static int s2255_create_sys_buffers(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03001944{
1945 unsigned long i;
1946 unsigned long reqsize;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001947 vc->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03001948 /* always allocate maximum size(PAL) for system buffers */
1949 reqsize = SYS_FRAMES_MAXSIZE;
1950
1951 if (reqsize > SYS_FRAMES_MAXSIZE)
1952 reqsize = SYS_FRAMES_MAXSIZE;
1953
1954 for (i = 0; i < SYS_FRAMES; i++) {
1955 /* allocate the frames */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001956 vc->buffer.frame[i].lpvbits = vmalloc(reqsize);
1957 vc->buffer.frame[i].size = reqsize;
1958 if (vc->buffer.frame[i].lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03001959 pr_info("out of memory. using less frames\n");
Dean Anderson5e950fa2014-02-04 18:16:24 -03001960 vc->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03001961 break;
1962 }
1963 }
1964
1965 /* make sure internal states are set */
1966 for (i = 0; i < SYS_FRAMES; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001967 vc->buffer.frame[i].ulState = 0;
1968 vc->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001969 }
1970
Dean Anderson5e950fa2014-02-04 18:16:24 -03001971 vc->cur_frame = 0;
1972 vc->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03001973 return 0;
1974}
1975
Dean Anderson5e950fa2014-02-04 18:16:24 -03001976static int s2255_release_sys_buffers(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03001977{
1978 unsigned long i;
Dean Anderson38f993a2008-06-26 23:15:51 -03001979 for (i = 0; i < SYS_FRAMES; i++) {
Markus Elfring83f56f72014-11-20 09:26:36 -03001980 vfree(vc->buffer.frame[i].lpvbits);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001981 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 }
Julia Lawall8bf554c2014-12-26 11:35:33 -03002280 setup_timer(&dev->timer, s2255_timer, (unsigned long)dev->fw_data);
Dean Anderson38f993a2008-06-26 23:15:51 -03002281 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002282 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002283 struct s2255_vc *vc = &dev->vc[i];
2284 vc->idx = i;
2285 vc->dev = dev;
2286 init_waitqueue_head(&vc->wait_setmode);
2287 init_waitqueue_head(&vc->wait_vidstatus);
sensoray-dev340a30c2014-02-12 17:25:45 -03002288 spin_lock_init(&vc->qlock);
2289 mutex_init(&vc->vb_lock);
Dean Anderson4de39f52010-03-03 19:39:19 -03002290 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002291
2292 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002293 if (!dev->fw_data->fw_urb) {
2294 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002295 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002296 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002297
Dean Anderson38f993a2008-06-26 23:15:51 -03002298 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2299 if (!dev->fw_data->pfw_data) {
2300 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002301 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002302 }
2303 /* load the first chunk */
2304 if (request_firmware(&dev->fw_data->fw,
2305 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
sensoray-devf5402002014-01-29 15:24:07 -03002306 dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002307 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002308 }
Dean Anderson14d96262008-08-25 13:58:55 -03002309 /* check the firmware is valid */
2310 fw_size = dev->fw_data->fw->size;
2311 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002312
Dean Anderson14d96262008-08-25 13:58:55 -03002313 if (*pdata != S2255_FW_MARKER) {
sensoray-devf5402002014-01-29 15:24:07 -03002314 dev_err(&interface->dev, "Firmware invalid.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002315 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002316 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002317 } else {
2318 /* make sure firmware is the latest */
2319 __le32 *pRel;
2320 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
sensoray-devf5402002014-01-29 15:24:07 -03002321 pr_info("s2255 dsp fw version %x\n", le32_to_cpu(*pRel));
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002322 dev->dsp_fw_ver = le32_to_cpu(*pRel);
2323 if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002324 pr_info("s2255: f2255usb.bin out of date.\n");
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002325 if (dev->pid == 0x2257 &&
2326 dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
sensoray-devf5402002014-01-29 15:24:07 -03002327 pr_warn("2257 needs firmware %d or above.\n",
2328 S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002329 }
Dean Anderson14d96262008-08-25 13:58:55 -03002330 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002331 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002332 retval = s2255_board_init(dev);
2333 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002334 goto errorBOARDINIT;
Dean Anderson14d96262008-08-25 13:58:55 -03002335 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002336 /* loads v4l specific */
2337 retval = s2255_probe_v4l(dev);
2338 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002339 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002340 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2341 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002342errorBOARDINIT:
2343 s2255_board_shutdown(dev);
2344errorFWMARKER:
2345 release_firmware(dev->fw_data->fw);
2346errorREQFW:
2347 kfree(dev->fw_data->pfw_data);
2348errorFWDATA2:
2349 usb_free_urb(dev->fw_data->fw_urb);
2350errorFWURB:
Kirill Tkhai9f6be2b2014-04-17 17:47:04 -03002351 del_timer_sync(&dev->timer);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002352errorEP:
2353 usb_put_dev(dev->udev);
2354errorUDEV:
2355 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002356 mutex_destroy(&dev->lock);
2357errorFWDATA1:
Dean Anderson47d8c882014-02-05 15:43:51 -03002358 kfree(dev->cmdbuf);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002359 kfree(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002360 pr_warn("Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002361 return retval;
2362}
2363
2364/* disconnect routine. when board is removed physically or with rmmod */
2365static void s2255_disconnect(struct usb_interface *interface)
2366{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002367 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002368 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002369 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002370 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002371 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002372 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002373 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002374 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002375 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002376 for (i = 0; i < channels; i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002377 video_unregister_device(&dev->vc[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002378 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002379 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2380 wake_up(&dev->fw_data->wait_fw);
2381 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002382 dev->vc[i].setmode_ready = 1;
2383 wake_up(&dev->vc[i].wait_setmode);
2384 dev->vc[i].vidstatus_ready = 1;
2385 wake_up(&dev->vc[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002386 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002387 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002388 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002389 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002390}
2391
2392static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002393 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002394 .probe = s2255_probe,
2395 .disconnect = s2255_disconnect,
2396 .id_table = s2255_table,
2397};
2398
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002399module_usb_driver(s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002400
2401MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2402MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2403MODULE_LICENSE("GPL");
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03002404MODULE_VERSION(S2255_VERSION);
Tim Gardner1bec9822012-07-24 16:52:27 -03002405MODULE_FIRMWARE(FIRMWARE_FILE_NAME);