blob: 1d4ba2b804908f9373de73100ccca4289032295b [file] [log] [blame]
Dean Anderson38f993a2008-06-26 23:15:51 -03001/*
2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
3 *
Dean Andersond86c6a82014-02-04 17:18:03 -03004 * Copyright (C) 2007-2014 by Sensoray Company Inc.
Dean Anderson38f993a2008-06-26 23:15:51 -03005 * Dean Anderson
6 *
7 * Some video buffer code based on vivi driver:
8 *
9 * Sensoray 2255 device supports 4 simultaneous channels.
10 * The channels are not "crossbar" inputs, they are physically
11 * attached to separate video decoders.
12 *
13 * Because of USB2.0 bandwidth limitations. There is only a
14 * certain amount of data which may be transferred at one time.
15 *
16 * Example maximum bandwidth utilization:
17 *
18 * -full size, color mode YUYV or YUV422P: 2 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030019 * -full or half size Grey scale: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030020 * -half size, color mode YUYV or YUV422P: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030021 * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
22 * at once.
Dean Anderson38f993a2008-06-26 23:15:51 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * (at your option) any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 */
38
39#include <linux/module.h>
40#include <linux/firmware.h>
41#include <linux/kernel.h>
42#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090043#include <linux/slab.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030044#include <linux/videodev2.h>
Hans Verkuilfeb75f02008-07-27 06:30:21 -030045#include <linux/mm.h>
Hans Verkuil44d06d82013-02-15 05:59:00 -030046#include <linux/vmalloc.h>
47#include <linux/usb.h>
sensoray-dev340a30c2014-02-12 17:25:45 -030048#include <media/videobuf2-vmalloc.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030049#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030050#include <media/v4l2-device.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030051#include <media/v4l2-ioctl.h>
Hans Verkuil192f1e72013-02-15 05:51:21 -030052#include <media/v4l2-ctrls.h>
Hans Verkuil44d06d82013-02-15 05:59:00 -030053#include <media/v4l2-event.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030054
sensoray-dev340a30c2014-02-12 17:25:45 -030055#define S2255_VERSION "1.25.1"
Dean Anderson38f993a2008-06-26 23:15:51 -030056#define FIRMWARE_FILE_NAME "f2255usb.bin"
57
Dean Anderson22b88d42008-08-29 15:33:19 -030058/* default JPEG quality */
59#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030060/* vendor request in */
61#define S2255_VR_IN 0
62/* vendor request out */
63#define S2255_VR_OUT 1
64/* firmware query */
65#define S2255_VR_FW 0x30
66/* USB endpoint number for configuring the device */
67#define S2255_CONFIG_EP 2
68/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030069#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030070/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030071#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson9da62eb2014-02-05 14:58:06 -030072#define S2255_MIN_BUFS 2
Dean Anderson14d96262008-08-25 13:58:55 -030073#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030074#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030075#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
76#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
77#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
78#define S2255_RESPONSE_FW cpu_to_le32(0x10)
79#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030080#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030081#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030082#define SYS_FRAMES 4
83/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030084#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
85#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030086#define LINE_SZ_4CIFS_NTSC 640
87#define LINE_SZ_2CIFS_NTSC 640
88#define LINE_SZ_1CIFS_NTSC 320
89#define LINE_SZ_4CIFS_PAL 704
90#define LINE_SZ_2CIFS_PAL 704
91#define LINE_SZ_1CIFS_PAL 352
92#define NUM_LINES_4CIFS_NTSC 240
93#define NUM_LINES_2CIFS_NTSC 240
94#define NUM_LINES_1CIFS_NTSC 240
95#define NUM_LINES_4CIFS_PAL 288
96#define NUM_LINES_2CIFS_PAL 288
97#define NUM_LINES_1CIFS_PAL 288
98#define LINE_SZ_DEF 640
99#define NUM_LINES_DEF 240
100
101
102/* predefined settings */
103#define FORMAT_NTSC 1
104#define FORMAT_PAL 2
105
106#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
107#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
108#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -0300109/* SCALE_4CIFSI is the 2 fields interpolated into one */
110#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -0300111
112#define COLOR_YUVPL 1 /* YUV planar */
113#define COLOR_YUVPK 2 /* YUV packed */
114#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300115#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300116
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300117#define MASK_COLOR 0x000000ff
118#define MASK_JPG_QUALITY 0x0000ff00
119#define MASK_INPUT_TYPE 0x000f0000
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300120/* frame decimation. */
Dean Anderson38f993a2008-06-26 23:15:51 -0300121#define FDEC_1 1 /* capture every frame. default */
122#define FDEC_2 2 /* capture every 2nd frame */
123#define FDEC_3 3 /* capture every 3rd frame */
124#define FDEC_5 5 /* capture every 5th frame */
125
126/*-------------------------------------------------------
127 * Default mode parameters.
128 *-------------------------------------------------------*/
129#define DEF_SCALE SCALE_4CIFS
130#define DEF_COLOR COLOR_YUVPL
131#define DEF_FDEC FDEC_1
132#define DEF_BRIGHT 0
133#define DEF_CONTRAST 0x5c
134#define DEF_SATURATION 0x80
135#define DEF_HUE 0
136
137/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300138#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
Dan Carpenter3b2a6302012-02-17 02:44:10 -0300139#define CMD_2255 0xc2255000
Dean Anderson3fa00602010-03-04 20:47:33 -0300140#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
141#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
142#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
143#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300144
145struct s2255_mode {
146 u32 format; /* input video format (NTSC, PAL) */
147 u32 scale; /* output video scale */
148 u32 color; /* output video color format */
149 u32 fdec; /* frame decimation */
150 u32 bright; /* brightness */
151 u32 contrast; /* contrast */
152 u32 saturation; /* saturation */
153 u32 hue; /* hue (NTSC only)*/
154 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
155 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
156 u32 restart; /* if DSP requires restart */
157};
158
Dean Anderson14d96262008-08-25 13:58:55 -0300159
160#define S2255_READ_IDLE 0
161#define S2255_READ_FRAME 1
162
Dean Anderson38f993a2008-06-26 23:15:51 -0300163/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300164struct s2255_framei {
165 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300166 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300167 void *lpvbits; /* image data */
168 unsigned long cur_size; /* current data copied to it */
169};
170
171/* image buffer structure */
172struct s2255_bufferi {
173 unsigned long dwFrames; /* number of frames in buffer */
174 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
175};
176
177#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
178 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300179 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300180
Dean Anderson38f993a2008-06-26 23:15:51 -0300181/* for firmware loading, fw_state */
182#define S2255_FW_NOTLOADED 0
183#define S2255_FW_LOADED_DSPWAIT 1
184#define S2255_FW_SUCCESS 2
185#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300186#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300187#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300188/* 2255 read states */
189#define S2255_READ_IDLE 0
190#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300191struct s2255_fw {
192 int fw_loaded;
193 int fw_size;
194 struct urb *fw_urb;
195 atomic_t fw_state;
196 void *pfw_data;
197 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300198 const struct firmware *fw;
199};
200
201struct s2255_pipeinfo {
202 u32 max_transfer_size;
203 u32 cur_transfer_size;
204 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300205 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300206 void *stream_urb;
207 void *dev; /* back pointer to s2255_dev struct*/
208 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300209 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300210};
211
212struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300213struct s2255_dev;
214
Dean Anderson5e950fa2014-02-04 18:16:24 -0300215/* 2255 video channel */
216struct s2255_vc {
sensoray-devf5402002014-01-29 15:24:07 -0300217 struct s2255_dev *dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300218 struct video_device vdev;
Hans Verkuil192f1e72013-02-15 05:51:21 -0300219 struct v4l2_ctrl_handler hdl;
Hans Verkuil7041dec2013-02-15 05:53:45 -0300220 struct v4l2_ctrl *jpegqual_ctrl;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300221 int resources;
Dean Andersond86c6a82014-02-04 17:18:03 -0300222 struct list_head buf_list;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300223 struct s2255_bufferi buffer;
224 struct s2255_mode mode;
Hans Verkuil469af772013-02-15 06:12:58 -0300225 v4l2_std_id std;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300226 /* jpeg compression */
Hans Verkuil7041dec2013-02-15 05:53:45 -0300227 unsigned jpegqual;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300228 /* capture parameters (for high quality mode full size) */
229 struct v4l2_captureparm cap_parm;
230 int cur_frame;
231 int last_frame;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300232 /* allocated image size */
233 unsigned long req_image_size;
234 /* received packet size */
235 unsigned long pkt_size;
236 int bad_payload;
237 unsigned long frame_count;
238 /* if JPEG image */
239 int jpg_size;
240 /* if channel configured to default state */
241 int configured;
242 wait_queue_head_t wait_setmode;
243 int setmode_ready;
244 /* video status items */
245 int vidstatus;
246 wait_queue_head_t wait_vidstatus;
247 int vidstatus_ready;
248 unsigned int width;
249 unsigned int height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300250 enum v4l2_field field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300251 const struct s2255_fmt *fmt;
252 int idx; /* channel number on device, 0-3 */
sensoray-dev340a30c2014-02-12 17:25:45 -0300253 struct vb2_queue vb_vidq;
254 struct mutex vb_lock; /* streaming lock */
255 spinlock_t qlock;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300256};
257
Dean Anderson38f993a2008-06-26 23:15:51 -0300258
259struct s2255_dev {
Dean Anderson5e950fa2014-02-04 18:16:24 -0300260 struct s2255_vc vc[MAX_CHANNELS];
sensoray-devf5402002014-01-29 15:24:07 -0300261 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300262 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300263 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300264 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson47d8c882014-02-05 15:43:51 -0300265 struct mutex cmdlock; /* protects cmdbuf */
Dean Anderson38f993a2008-06-26 23:15:51 -0300266 struct usb_device *udev;
267 struct usb_interface *interface;
268 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300269 struct timer_list timer;
270 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300271 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300272 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300273 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300274 int chn_ready;
Dean Anderson4de39f52010-03-03 19:39:19 -0300275 /* dsp firmware version (f2255usb.bin) */
276 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300277 u16 pid; /* product id */
Dean Anderson47d8c882014-02-05 15:43:51 -0300278#define S2255_CMDBUF_SIZE 512
279 __le32 *cmdbuf;
Dean Anderson38f993a2008-06-26 23:15:51 -0300280};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300281
Dean Anderson65c6edb2010-04-20 17:21:32 -0300282static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
283{
284 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
285}
Dean Anderson38f993a2008-06-26 23:15:51 -0300286
287struct s2255_fmt {
288 char *name;
289 u32 fourcc;
290 int depth;
291};
292
293/* buffer for one video frame */
294struct s2255_buffer {
295 /* common v4l buffer stuff -- must be first */
sensoray-dev340a30c2014-02-12 17:25:45 -0300296 struct vb2_buffer vb;
297 struct list_head list;
Dean Anderson38f993a2008-06-26 23:15:51 -0300298};
299
Dean Anderson38f993a2008-06-26 23:15:51 -0300300
Dean Andersonabce21f2009-04-23 16:04:41 -0300301/* current cypress EEPROM firmware version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300302#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
Dean Anderson4de39f52010-03-03 19:39:19 -0300303/* current DSP FW version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300304#define S2255_CUR_DSP_FWVER 10104
Dean Anderson4de39f52010-03-03 19:39:19 -0300305/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300306#define S2255_MIN_DSP_STATUS 5
307#define S2255_MIN_DSP_COLORFILTER 8
Hans Verkuil469af772013-02-15 06:12:58 -0300308#define S2255_NORMS (V4L2_STD_ALL)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300309
310/* private V4L2 controls */
311
312/*
313 * The following chart displays how COLORFILTER should be set
314 * =========================================================
315 * = fourcc = COLORFILTER =
316 * = ===============================
317 * = = 0 = 1 =
318 * =========================================================
319 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
320 * = = s-video or = composite =
321 * = = B/W camera = input =
322 * =========================================================
323 * = other = color, svideo = color, =
324 * = = = composite =
325 * =========================================================
326 *
327 * Notes:
328 * channels 0-3 on 2255 are composite
329 * channels 0-1 on 2257 are composite, 2-3 are s-video
330 * If COLORFILTER is 0 with a composite color camera connected,
331 * the output will appear monochrome but hatching
332 * will occur.
333 * COLORFILTER is different from "color killer" and "color effects"
334 * for reasons above.
335 */
336#define S2255_V4L2_YC_ON 1
337#define S2255_V4L2_YC_OFF 0
Hans Verkuil192f1e72013-02-15 05:51:21 -0300338#define V4L2_CID_S2255_COLORFILTER (V4L2_CID_USER_S2255_BASE + 0)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300339
Dean Anderson38f993a2008-06-26 23:15:51 -0300340/* frame prefix size (sent once every frame) */
341#define PREFIX_SIZE 512
342
343/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300344static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300345
Dean Anderson38f993a2008-06-26 23:15:51 -0300346static int debug;
Dean Anderson38f993a2008-06-26 23:15:51 -0300347
348static int s2255_start_readpipe(struct s2255_dev *dev);
349static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300350static int s2255_start_acquire(struct s2255_vc *vc);
351static int s2255_stop_acquire(struct s2255_vc *vc);
352static void s2255_fillbuff(struct s2255_vc *vc, struct s2255_buffer *buf,
Dean Andersonfe85ce92010-06-01 19:12:07 -0300353 int jpgsize);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300354static int s2255_set_mode(struct s2255_vc *vc, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300355static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300356static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300357static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300358static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
359 u16 index, u16 value, void *buf,
360 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300361
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300362/* dev_err macro with driver name */
363#define S2255_DRIVER_NAME "s2255"
364#define s2255_dev_err(dev, fmt, arg...) \
365 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
366
sensoray-devf5402002014-01-29 15:24:07 -0300367#define dprintk(dev, level, fmt, arg...) \
368 v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
Dean Anderson38f993a2008-06-26 23:15:51 -0300369
Dean Anderson38f993a2008-06-26 23:15:51 -0300370static struct usb_driver s2255_driver;
371
Dean Anderson38f993a2008-06-26 23:15:51 -0300372/* start video number */
373static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
374
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300375/* Enable jpeg capture. */
376static int jpeg_enable = 1;
377
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300378module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300379MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300380module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300381MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300382module_param(jpeg_enable, int, 0644);
383MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
Dean Anderson38f993a2008-06-26 23:15:51 -0300384
385/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300386#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300387static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300388 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
389 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300390 { } /* Terminating entry */
391};
392MODULE_DEVICE_TABLE(usb, s2255_table);
393
Dean Anderson38f993a2008-06-26 23:15:51 -0300394#define BUFFER_TIMEOUT msecs_to_jiffies(400)
395
Dean Anderson38f993a2008-06-26 23:15:51 -0300396/* image formats. */
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300397/* JPEG formats must be defined last to support jpeg_enable parameter */
Dean Anderson38f993a2008-06-26 23:15:51 -0300398static const struct s2255_fmt formats[] = {
399 {
Dean Anderson38f993a2008-06-26 23:15:51 -0300400 .name = "4:2:2, packed, YUYV",
401 .fourcc = V4L2_PIX_FMT_YUYV,
402 .depth = 16
403
404 }, {
405 .name = "4:2:2, packed, UYVY",
406 .fourcc = V4L2_PIX_FMT_UYVY,
407 .depth = 16
408 }, {
Hans Verkuil5c632b22013-02-26 14:29:04 -0300409 .name = "4:2:2, planar, YUV422P",
410 .fourcc = V4L2_PIX_FMT_YUV422P,
411 .depth = 16
412
413 }, {
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300414 .name = "8bpp GREY",
415 .fourcc = V4L2_PIX_FMT_GREY,
416 .depth = 8
417 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300418 .name = "JPG",
419 .fourcc = V4L2_PIX_FMT_JPEG,
420 .depth = 24
421 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300422 .name = "MJPG",
423 .fourcc = V4L2_PIX_FMT_MJPEG,
424 .depth = 24
Dean Anderson38f993a2008-06-26 23:15:51 -0300425 }
426};
427
Dean Anderson5e950fa2014-02-04 18:16:24 -0300428static int norm_maxw(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300429{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300430 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300431 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
432}
433
Dean Anderson5e950fa2014-02-04 18:16:24 -0300434static int norm_maxh(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300435{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300436 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300437 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
438}
439
Dean Anderson5e950fa2014-02-04 18:16:24 -0300440static int norm_minw(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300441{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300442 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300443 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
444}
445
Dean Anderson5e950fa2014-02-04 18:16:24 -0300446static int norm_minh(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300447{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300448 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300449 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
450}
451
452
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300453/*
454 * TODO: fixme: move YUV reordering to hardware
455 * converts 2255 planar format to yuyv or uyvy
456 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300457static void planar422p_to_yuv_packed(const unsigned char *in,
458 unsigned char *out,
459 int width, int height,
460 int fmt)
461{
462 unsigned char *pY;
463 unsigned char *pCb;
464 unsigned char *pCr;
465 unsigned long size = height * width;
466 unsigned int i;
467 pY = (unsigned char *)in;
468 pCr = (unsigned char *)in + height * width;
469 pCb = (unsigned char *)in + height * width + (height * width / 2);
470 for (i = 0; i < size * 2; i += 4) {
471 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
472 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
473 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
474 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
475 }
476 return;
477}
478
Hans Verkuild45b9b82008-09-04 03:33:43 -0300479static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300480{
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300481 s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
sensoray-devf5402002014-01-29 15:24:07 -0300482 msleep(20);
Dean Anderson14d96262008-08-25 13:58:55 -0300483 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300484 msleep(600);
485 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300486 return;
487}
Dean Anderson38f993a2008-06-26 23:15:51 -0300488
489/* kickstarts the firmware loading. from probe
490 */
491static void s2255_timer(unsigned long user_data)
492{
493 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson38f993a2008-06-26 23:15:51 -0300494 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
sensoray-devf5402002014-01-29 15:24:07 -0300495 pr_err("s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300496 atomic_set(&data->fw_state, S2255_FW_FAILED);
497 /* wake up anything waiting for the firmware */
498 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300499 return;
500 }
501}
502
Dean Anderson38f993a2008-06-26 23:15:51 -0300503
504/* this loads the firmware asynchronously.
Hans Verkuil0b84caa2013-02-26 14:14:19 -0300505 Originally this was done synchronously in probe.
Dean Anderson38f993a2008-06-26 23:15:51 -0300506 But it is better to load it asynchronously here than block
507 inside the probe function. Blocking inside probe affects boot time.
508 FW loading is triggered by the timer in the probe function
509*/
510static void s2255_fwchunk_complete(struct urb *urb)
511{
512 struct s2255_fw *data = urb->context;
513 struct usb_device *udev = urb->dev;
514 int len;
Dean Anderson38f993a2008-06-26 23:15:51 -0300515 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300516 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300517 atomic_set(&data->fw_state, S2255_FW_FAILED);
518 /* wake up anything waiting for the firmware */
519 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300520 return;
521 }
522 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300523 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300524 atomic_set(&data->fw_state, S2255_FW_FAILED);
525 /* wake up anything waiting for the firmware */
526 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300527 return;
528 }
529#define CHUNK_SIZE 512
530 /* all USB transfers must be done with continuous kernel memory.
531 can't allocate more than 128k in current linux kernel, so
532 upload the firmware in chunks
533 */
534 if (data->fw_loaded < data->fw_size) {
535 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
536 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
537
538 if (len < CHUNK_SIZE)
539 memset(data->pfw_data, 0, CHUNK_SIZE);
540
Dean Anderson38f993a2008-06-26 23:15:51 -0300541 memcpy(data->pfw_data,
542 (char *) data->fw->data + data->fw_loaded, len);
543
544 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
545 data->pfw_data, CHUNK_SIZE,
546 s2255_fwchunk_complete, data);
547 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
548 dev_err(&udev->dev, "failed submit URB\n");
549 atomic_set(&data->fw_state, S2255_FW_FAILED);
550 /* wake up anything waiting for the firmware */
551 wake_up(&data->wait_fw);
552 return;
553 }
554 data->fw_loaded += len;
sensoray-devf5402002014-01-29 15:24:07 -0300555 } else
Dean Anderson38f993a2008-06-26 23:15:51 -0300556 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson38f993a2008-06-26 23:15:51 -0300557 return;
558
559}
560
Dean Anderson5e950fa2014-02-04 18:16:24 -0300561static int s2255_got_frame(struct s2255_vc *vc, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300562{
Dean Anderson38f993a2008-06-26 23:15:51 -0300563 struct s2255_buffer *buf;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300564 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300565 unsigned long flags = 0;
566 int rc = 0;
sensoray-dev340a30c2014-02-12 17:25:45 -0300567 spin_lock_irqsave(&vc->qlock, flags);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300568 if (list_empty(&vc->buf_list)) {
sensoray-devf5402002014-01-29 15:24:07 -0300569 dprintk(dev, 1, "No active queue to serve\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300570 rc = -1;
571 goto unlock;
572 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300573 buf = list_entry(vc->buf_list.next,
sensoray-dev340a30c2014-02-12 17:25:45 -0300574 struct s2255_buffer, list);
575 list_del(&buf->list);
576 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300577 s2255_fillbuff(vc, buf, jpgsize);
sensoray-dev340a30c2014-02-12 17:25:45 -0300578 dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf);
Dean Anderson38f993a2008-06-26 23:15:51 -0300579unlock:
sensoray-dev340a30c2014-02-12 17:25:45 -0300580 spin_unlock_irqrestore(&vc->qlock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300581 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300582}
583
Dean Anderson38f993a2008-06-26 23:15:51 -0300584static const struct s2255_fmt *format_by_fourcc(int fourcc)
585{
586 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300587 for (i = 0; i < ARRAY_SIZE(formats); i++) {
588 if (-1 == formats[i].fourcc)
589 continue;
sensoray-devf5402002014-01-29 15:24:07 -0300590 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
591 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
592 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300593 if (formats[i].fourcc == fourcc)
594 return formats + i;
595 }
596 return NULL;
597}
598
Dean Anderson38f993a2008-06-26 23:15:51 -0300599/* video buffer vmalloc implementation based partly on VIVI driver which is
600 * Copyright (c) 2006 by
601 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
602 * Ted Walther <ted--a.t--enumera.com>
603 * John Sokol <sokol--a.t--videotechnology.com>
604 * http://v4l.videotechnology.com/
605 *
606 */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300607static void s2255_fillbuff(struct s2255_vc *vc,
Dean Andersonfe85ce92010-06-01 19:12:07 -0300608 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300609{
610 int pos = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300611 const char *tmpbuf;
sensoray-dev340a30c2014-02-12 17:25:45 -0300612 char *vbuf = vb2_plane_vaddr(&buf->vb, 0);
Dean Anderson38f993a2008-06-26 23:15:51 -0300613 unsigned long last_frame;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300614 struct s2255_dev *dev = vc->dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300615
616 if (!vbuf)
617 return;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300618 last_frame = vc->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300619 if (last_frame != -1) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300620 tmpbuf =
Dean Anderson5e950fa2014-02-04 18:16:24 -0300621 (const char *)vc->buffer.frame[last_frame].lpvbits;
Dean Anderson8bf405a2014-02-05 15:18:55 -0300622 switch (vc->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300623 case V4L2_PIX_FMT_YUYV:
624 case V4L2_PIX_FMT_UYVY:
625 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
sensoray-dev340a30c2014-02-12 17:25:45 -0300626 vbuf, vc->width,
627 vc->height,
Dean Anderson8bf405a2014-02-05 15:18:55 -0300628 vc->fmt->fourcc);
Dean Anderson38f993a2008-06-26 23:15:51 -0300629 break;
630 case V4L2_PIX_FMT_GREY:
sensoray-dev340a30c2014-02-12 17:25:45 -0300631 memcpy(vbuf, tmpbuf, vc->width * vc->height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300632 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300633 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300634 case V4L2_PIX_FMT_MJPEG:
sensoray-dev340a30c2014-02-12 17:25:45 -0300635 buf->vb.v4l2_buf.length = jpgsize;
636 memcpy(vbuf, tmpbuf, jpgsize);
Dean Anderson14d96262008-08-25 13:58:55 -0300637 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300638 case V4L2_PIX_FMT_YUV422P:
639 memcpy(vbuf, tmpbuf,
sensoray-dev340a30c2014-02-12 17:25:45 -0300640 vc->width * vc->height * 2);
Dean Anderson38f993a2008-06-26 23:15:51 -0300641 break;
642 default:
sensoray-devf5402002014-01-29 15:24:07 -0300643 pr_info("s2255: unknown format?\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300644 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300645 vc->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300646 } else {
sensoray-devf5402002014-01-29 15:24:07 -0300647 pr_err("s2255: =======no frame\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300648 return;
Dean Anderson38f993a2008-06-26 23:15:51 -0300649 }
sensoray-devf5402002014-01-29 15:24:07 -0300650 dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n",
Dean Anderson38f993a2008-06-26 23:15:51 -0300651 (unsigned long)vbuf, pos);
652 /* tell v4l buffer was filled */
sensoray-dev340a30c2014-02-12 17:25:45 -0300653 buf->vb.v4l2_buf.field = vc->field;
654 buf->vb.v4l2_buf.sequence = vc->frame_count;
655 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
656 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
Dean Anderson38f993a2008-06-26 23:15:51 -0300657}
658
659
660/* ------------------------------------------------------------------
661 Videobuf operations
662 ------------------------------------------------------------------*/
663
sensoray-dev340a30c2014-02-12 17:25:45 -0300664static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
665 unsigned int *nbuffers, unsigned int *nplanes,
666 unsigned int sizes[], void *alloc_ctxs[])
Dean Anderson38f993a2008-06-26 23:15:51 -0300667{
sensoray-dev340a30c2014-02-12 17:25:45 -0300668 struct s2255_vc *vc = vb2_get_drv_priv(vq);
Dean Anderson9da62eb2014-02-05 14:58:06 -0300669 if (*nbuffers < S2255_MIN_BUFS)
670 *nbuffers = S2255_MIN_BUFS;
sensoray-dev340a30c2014-02-12 17:25:45 -0300671 *nplanes = 1;
672 sizes[0] = vc->width * vc->height * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300673 return 0;
674}
675
sensoray-dev340a30c2014-02-12 17:25:45 -0300676static int buffer_prepare(struct vb2_buffer *vb)
Dean Anderson38f993a2008-06-26 23:15:51 -0300677{
sensoray-dev340a30c2014-02-12 17:25:45 -0300678 struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300679 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300680 int w = vc->width;
681 int h = vc->height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300682 unsigned long size;
683
684 dprintk(vc->dev, 4, "%s\n", __func__);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300685 if (vc->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300686 return -EINVAL;
687
Dean Anderson5e950fa2014-02-04 18:16:24 -0300688 if ((w < norm_minw(vc)) ||
689 (w > norm_maxw(vc)) ||
690 (h < norm_minh(vc)) ||
691 (h > norm_maxh(vc))) {
Dean Anderson92cde472014-02-05 17:38:42 -0300692 dprintk(vc->dev, 4, "invalid buffer prepare\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300693 return -EINVAL;
694 }
sensoray-dev340a30c2014-02-12 17:25:45 -0300695 size = w * h * (vc->fmt->depth >> 3);
696 if (vb2_plane_size(vb, 0) < size) {
Dean Anderson92cde472014-02-05 17:38:42 -0300697 dprintk(vc->dev, 4, "invalid buffer prepare\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300698 return -EINVAL;
699 }
700
sensoray-dev340a30c2014-02-12 17:25:45 -0300701 vb2_set_plane_payload(&buf->vb, 0, size);
Dean Anderson38f993a2008-06-26 23:15:51 -0300702 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300703}
704
sensoray-dev340a30c2014-02-12 17:25:45 -0300705static void buffer_queue(struct vb2_buffer *vb)
Dean Anderson38f993a2008-06-26 23:15:51 -0300706{
707 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
sensoray-dev340a30c2014-02-12 17:25:45 -0300708 struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
709 unsigned long flags = 0;
Dean Anderson92cde472014-02-05 17:38:42 -0300710 dprintk(vc->dev, 1, "%s\n", __func__);
sensoray-dev340a30c2014-02-12 17:25:45 -0300711 spin_lock_irqsave(&vc->qlock, flags);
712 list_add_tail(&buf->list, &vc->buf_list);
713 spin_unlock_irqrestore(&vc->qlock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300714}
715
sensoray-dev340a30c2014-02-12 17:25:45 -0300716static int start_streaming(struct vb2_queue *vq, unsigned int count);
717static int stop_streaming(struct vb2_queue *vq);
Dean Anderson38f993a2008-06-26 23:15:51 -0300718
sensoray-dev340a30c2014-02-12 17:25:45 -0300719static struct vb2_ops s2255_video_qops = {
720 .queue_setup = queue_setup,
Dean Anderson38f993a2008-06-26 23:15:51 -0300721 .buf_prepare = buffer_prepare,
722 .buf_queue = buffer_queue,
sensoray-dev340a30c2014-02-12 17:25:45 -0300723 .start_streaming = start_streaming,
724 .stop_streaming = stop_streaming,
725 .wait_prepare = vb2_ops_wait_prepare,
726 .wait_finish = vb2_ops_wait_finish,
Dean Anderson38f993a2008-06-26 23:15:51 -0300727};
728
Dean Anderson38f993a2008-06-26 23:15:51 -0300729static int vidioc_querycap(struct file *file, void *priv,
730 struct v4l2_capability *cap)
731{
sensoray-dev340a30c2014-02-12 17:25:45 -0300732 struct s2255_vc *vc = video_drvdata(file);
733 struct s2255_dev *dev = vc->dev;
Hans Verkuil39696002013-02-07 07:06:21 -0300734
Dean Anderson38f993a2008-06-26 23:15:51 -0300735 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
736 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300737 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
sensoray-dev340a30c2014-02-12 17:25:45 -0300738 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
739 V4L2_CAP_READWRITE;
Hans Verkuil39696002013-02-07 07:06:21 -0300740 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300741 return 0;
742}
743
744static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
745 struct v4l2_fmtdesc *f)
746{
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300747 int index = f->index;
Dean Anderson38f993a2008-06-26 23:15:51 -0300748
749 if (index >= ARRAY_SIZE(formats))
750 return -EINVAL;
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300751 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
752 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
753 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300754 strlcpy(f->description, formats[index].name, sizeof(f->description));
755 f->pixelformat = formats[index].fourcc;
756 return 0;
757}
758
759static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
760 struct v4l2_format *f)
761{
sensoray-dev340a30c2014-02-12 17:25:45 -0300762 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300763 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300764
Dean Anderson5e950fa2014-02-04 18:16:24 -0300765 f->fmt.pix.width = vc->width;
766 f->fmt.pix.height = vc->height;
Hans Verkuil92513612013-02-15 06:05:08 -0300767 if (f->fmt.pix.height >=
768 (is_ntsc ? NUM_LINES_1CIFS_NTSC : NUM_LINES_1CIFS_PAL) * 2)
769 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
770 else
771 f->fmt.pix.field = V4L2_FIELD_TOP;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300772 f->fmt.pix.pixelformat = vc->fmt->fourcc;
773 f->fmt.pix.bytesperline = f->fmt.pix.width * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300774 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300775 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
776 f->fmt.pix.priv = 0;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300777 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300778}
779
780static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
781 struct v4l2_format *f)
782{
783 const struct s2255_fmt *fmt;
784 enum v4l2_field field;
sensoray-dev340a30c2014-02-12 17:25:45 -0300785 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300786 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300787
788 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
789
790 if (fmt == NULL)
791 return -EINVAL;
792
793 field = f->fmt.pix.field;
Dean Anderson38f993a2008-06-26 23:15:51 -0300794
Dean Anderson92cde472014-02-05 17:38:42 -0300795 dprintk(vc->dev, 50, "%s NTSC: %d suggested width: %d, height: %d\n",
Dean Anderson85b85482010-04-08 23:51:17 -0300796 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300797 if (is_ntsc) {
798 /* NTSC */
799 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
800 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300801 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300802 } else {
803 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
Hans Verkuil92513612013-02-15 06:05:08 -0300804 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300805 }
806 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
807 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
808 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
809 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
810 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
811 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
812 else
813 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
814 } else {
815 /* PAL */
816 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
817 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300818 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300819 } else {
820 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300821 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300822 }
Hans Verkuil92513612013-02-15 06:05:08 -0300823 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300824 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300825 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300826 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300827 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300828 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300829 else
Dean Anderson38f993a2008-06-26 23:15:51 -0300830 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300831 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300832 f->fmt.pix.field = field;
833 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
834 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300835 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
836 f->fmt.pix.priv = 0;
Dean Anderson92cde472014-02-05 17:38:42 -0300837 dprintk(vc->dev, 50, "%s: set width %d height %d field %d\n", __func__,
Dean Anderson85b85482010-04-08 23:51:17 -0300838 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300839 return 0;
840}
841
842static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
843 struct v4l2_format *f)
844{
sensoray-dev340a30c2014-02-12 17:25:45 -0300845 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson38f993a2008-06-26 23:15:51 -0300846 const struct s2255_fmt *fmt;
sensoray-dev340a30c2014-02-12 17:25:45 -0300847 struct vb2_queue *q = &vc->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300848 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300849 int ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300850
sensoray-dev340a30c2014-02-12 17:25:45 -0300851 ret = vidioc_try_fmt_vid_cap(file, vc, f);
Dean Anderson38f993a2008-06-26 23:15:51 -0300852
853 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300854 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300855
856 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
857
858 if (fmt == NULL)
859 return -EINVAL;
860
sensoray-dev340a30c2014-02-12 17:25:45 -0300861 if (vb2_is_busy(q)) {
Dean Anderson92cde472014-02-05 17:38:42 -0300862 dprintk(vc->dev, 1, "queue busy\n");
sensoray-dev340a30c2014-02-12 17:25:45 -0300863 return -EBUSY;
Dean Anderson38f993a2008-06-26 23:15:51 -0300864 }
865
Dean Anderson5e950fa2014-02-04 18:16:24 -0300866 mode = vc->mode;
867 vc->fmt = fmt;
868 vc->width = f->fmt.pix.width;
869 vc->height = f->fmt.pix.height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300870 vc->field = f->fmt.pix.field;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300871 if (vc->width > norm_minw(vc)) {
872 if (vc->height > norm_minh(vc)) {
873 if (vc->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -0300874 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300875 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -0300876 else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300877 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -0300878 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300879 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300880
881 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300882 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300883 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300884 /* color mode */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300885 switch (vc->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300886 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300887 mode.color &= ~MASK_COLOR;
888 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -0300889 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300890 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300891 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300892 mode.color &= ~MASK_COLOR;
893 mode.color |= COLOR_JPG;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300894 mode.color |= (vc->jpegqual << 8);
Dean Anderson14d96262008-08-25 13:58:55 -0300895 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300896 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300897 mode.color &= ~MASK_COLOR;
898 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300899 break;
900 case V4L2_PIX_FMT_YUYV:
901 case V4L2_PIX_FMT_UYVY:
902 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300903 mode.color &= ~MASK_COLOR;
904 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -0300905 break;
906 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300907 if ((mode.color & MASK_COLOR) != (vc->mode.color & MASK_COLOR))
Dean Andersonfe85ce92010-06-01 19:12:07 -0300908 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300909 else if (mode.scale != vc->mode.scale)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300910 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300911 else if (mode.format != vc->mode.format)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300912 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300913 vc->mode = mode;
914 (void) s2255_set_mode(vc, &mode);
sensoray-dev340a30c2014-02-12 17:25:45 -0300915 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300916}
917
Dean Anderson38f993a2008-06-26 23:15:51 -0300918
Dean Anderson38f993a2008-06-26 23:15:51 -0300919/* write to the configuration pipe, synchronously */
920static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
921 int size)
922{
923 int pipe;
924 int done;
925 long retval = -1;
926 if (udev) {
927 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
928 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
929 }
930 return retval;
931}
932
933static u32 get_transfer_size(struct s2255_mode *mode)
934{
935 int linesPerFrame = LINE_SZ_DEF;
936 int pixelsPerLine = NUM_LINES_DEF;
937 u32 outImageSize;
938 u32 usbInSize;
939 unsigned int mask_mult;
940
941 if (mode == NULL)
942 return 0;
943
944 if (mode->format == FORMAT_NTSC) {
945 switch (mode->scale) {
946 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -0300947 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -0300948 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
949 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
950 break;
951 case SCALE_2CIFS:
952 linesPerFrame = NUM_LINES_2CIFS_NTSC;
953 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
954 break;
955 case SCALE_1CIFS:
956 linesPerFrame = NUM_LINES_1CIFS_NTSC;
957 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
958 break;
959 default:
960 break;
961 }
962 } else if (mode->format == FORMAT_PAL) {
963 switch (mode->scale) {
964 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -0300965 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -0300966 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
967 pixelsPerLine = LINE_SZ_4CIFS_PAL;
968 break;
969 case SCALE_2CIFS:
970 linesPerFrame = NUM_LINES_2CIFS_PAL;
971 pixelsPerLine = LINE_SZ_2CIFS_PAL;
972 break;
973 case SCALE_1CIFS:
974 linesPerFrame = NUM_LINES_1CIFS_PAL;
975 pixelsPerLine = LINE_SZ_1CIFS_PAL;
976 break;
977 default:
978 break;
979 }
980 }
981 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -0300982 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300983 /* 2 bytes/pixel if not monochrome */
984 outImageSize *= 2;
985 }
986
987 /* total bytes to send including prefix and 4K padding;
988 must be a multiple of USB_READ_SIZE */
989 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
990 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
991 /* if size not a multiple of USB_READ_SIZE */
992 if (usbInSize & ~mask_mult)
993 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
994 return usbInSize;
995}
996
Dean Anderson85b85482010-04-08 23:51:17 -0300997static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -0300998{
999 struct device *dev = &sdev->udev->dev;
1000 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001001 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1002 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001003 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001004 dev_info(dev, "------------------------------------------------\n");
1005}
1006
1007/*
1008 * set mode is the function which controls the DSP.
1009 * the restart parameter in struct s2255_mode should be set whenever
1010 * the image size could change via color format, video system or image
1011 * size.
1012 * When the restart parameter is set, we sleep for ONE frame to allow the
1013 * DSP time to get the new frame
1014 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001015static int s2255_set_mode(struct s2255_vc *vc,
Dean Anderson38f993a2008-06-26 23:15:51 -03001016 struct s2255_mode *mode)
1017{
1018 int res;
Dean Anderson38f993a2008-06-26 23:15:51 -03001019 unsigned long chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001020 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001021 int i;
Dean Anderson47d8c882014-02-05 15:43:51 -03001022 __le32 *buffer = dev->cmdbuf;
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001023
Dean Anderson47d8c882014-02-05 15:43:51 -03001024 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001025 chn_rev = G_chnmap[vc->idx];
1026 dprintk(dev, 3, "%s channel: %d\n", __func__, vc->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001027 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001028 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1029 mode->color &= ~MASK_COLOR;
1030 mode->color |= COLOR_JPG;
1031 mode->color &= ~MASK_JPG_QUALITY;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001032 mode->color |= (vc->jpegqual << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001033 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001034 /* save the mode */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001035 vc->mode = *mode;
1036 vc->req_image_size = get_transfer_size(mode);
1037 dprintk(dev, 1, "%s: reqsize %ld\n", __func__, vc->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001038 /* set the mode */
1039 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001040 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001041 buffer[2] = CMD_SET_MODE;
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001042 for (i = 0; i < sizeof(struct s2255_mode) / sizeof(u32); i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001043 buffer[3 + i] = cpu_to_le32(((u32 *)&vc->mode)[i]);
1044 vc->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001045 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1046 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001047 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001048 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001049 if (mode->restart) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001050 wait_event_timeout(vc->wait_setmode,
1051 (vc->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001052 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001053 if (vc->setmode_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001054 dprintk(dev, 0, "s2255: no set mode response\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001055 res = -EFAULT;
1056 }
1057 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001058 /* clear the restart flag */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001059 vc->mode.restart = 0;
1060 dprintk(dev, 1, "%s chn %d, result: %d\n", __func__, vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03001061 mutex_unlock(&dev->cmdlock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001062 return res;
1063}
1064
Dean Anderson5e950fa2014-02-04 18:16:24 -03001065static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001066{
1067 int res;
Dean Anderson4de39f52010-03-03 19:39:19 -03001068 u32 chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001069 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03001070 __le32 *buffer = dev->cmdbuf;
1071
1072 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001073 chn_rev = G_chnmap[vc->idx];
1074 dprintk(dev, 4, "%s chan %d\n", __func__, vc->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001075 /* form the get vid status command */
1076 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001077 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001078 buffer[2] = CMD_STATUS;
1079 *pstatus = 0;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001080 vc->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001081 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001082 wait_event_timeout(vc->wait_vidstatus,
1083 (vc->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001084 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001085 if (vc->vidstatus_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001086 dprintk(dev, 0, "s2255: no vidstatus response\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001087 res = -EFAULT;
1088 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001089 *pstatus = vc->vidstatus;
sensoray-devf5402002014-01-29 15:24:07 -03001090 dprintk(dev, 4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson47d8c882014-02-05 15:43:51 -03001091 mutex_unlock(&dev->cmdlock);
Dean Anderson4de39f52010-03-03 19:39:19 -03001092 return res;
1093}
1094
sensoray-dev340a30c2014-02-12 17:25:45 -03001095static int start_streaming(struct vb2_queue *vq, unsigned int count)
Dean Anderson38f993a2008-06-26 23:15:51 -03001096{
sensoray-dev340a30c2014-02-12 17:25:45 -03001097 struct s2255_vc *vc = vb2_get_drv_priv(vq);
Dean Anderson38f993a2008-06-26 23:15:51 -03001098 int j;
Dean Anderson92cde472014-02-05 17:38:42 -03001099
Dean Anderson5e950fa2014-02-04 18:16:24 -03001100 vc->last_frame = -1;
1101 vc->bad_payload = 0;
1102 vc->cur_frame = 0;
1103 vc->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001104 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001105 vc->buffer.frame[j].ulState = S2255_READ_IDLE;
1106 vc->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001107 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001108 return s2255_start_acquire(vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03001109}
1110
sensoray-dev340a30c2014-02-12 17:25:45 -03001111/* abort streaming and wait for last buffer */
1112static int stop_streaming(struct vb2_queue *vq)
Dean Anderson38f993a2008-06-26 23:15:51 -03001113{
sensoray-dev340a30c2014-02-12 17:25:45 -03001114 struct s2255_vc *vc = vb2_get_drv_priv(vq);
1115 struct s2255_buffer *buf, *node;
1116 unsigned long flags;
1117 (void) s2255_stop_acquire(vc);
1118 spin_lock_irqsave(&vc->qlock, flags);
1119 list_for_each_entry_safe(buf, node, &vc->buf_list, list) {
1120 list_del(&buf->list);
1121 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
1122 dprintk(vc->dev, 2, "[%p/%d] done\n",
1123 buf, buf->vb.v4l2_buf.index);
1124 }
1125 spin_unlock_irqrestore(&vc->qlock, flags);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001126 return 0;
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 */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001525 del_timer(&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;
1680 set_bit(V4L2_FL_USE_FH_PRIO, &vc->vdev.flags);
1681 video_set_drvdata(&vc->vdev, vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03001682 if (video_nr == -1)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001683 ret = video_register_device(&vc->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001684 VFL_TYPE_GRABBER,
1685 video_nr);
1686 else
Dean Anderson5e950fa2014-02-04 18:16:24 -03001687 ret = video_register_device(&vc->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001688 VFL_TYPE_GRABBER,
1689 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001690
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001691 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001692 dev_err(&dev->udev->dev,
1693 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001694 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001695 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001696 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001697 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Anderson5e950fa2014-02-04 18:16:24 -03001698 video_device_node_name(&vc->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001699
Dean Anderson38f993a2008-06-26 23:15:51 -03001700 }
sensoray-devf5402002014-01-29 15:24:07 -03001701 pr_info("Sensoray 2255 V4L driver Revision: %s\n",
1702 S2255_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001703 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001704 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001705 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001706 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001707 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001708 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
sensoray-devf5402002014-01-29 15:24:07 -03001709 pr_warn("s2255: Not all channels available.\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001710 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001711}
1712
Dean Anderson38f993a2008-06-26 23:15:51 -03001713/* this function moves the usb stream read pipe data
1714 * into the system buffers.
1715 * returns 0 on success, EAGAIN if more data to process( call this
1716 * function again).
1717 *
1718 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001719 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001720 * bytes 4-7: channel: 0-3
1721 * bytes 8-11: payload size: size of the frame
1722 * bytes 12-payloadsize+12: frame data
1723 */
1724static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1725{
Dean Anderson38f993a2008-06-26 23:15:51 -03001726 char *pdest;
1727 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001728 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001729 char *psrc;
1730 unsigned long copy_size;
1731 unsigned long size;
1732 s32 idx = -1;
1733 struct s2255_framei *frm;
1734 unsigned char *pdata;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001735 struct s2255_vc *vc;
sensoray-devf5402002014-01-29 15:24:07 -03001736 dprintk(dev, 100, "buffer to user\n");
Dean Anderson5e950fa2014-02-04 18:16:24 -03001737 vc = &dev->vc[dev->cc];
1738 idx = vc->cur_frame;
1739 frm = &vc->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001740 if (frm->ulState == S2255_READ_IDLE) {
1741 int jj;
1742 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03001743 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03001744 int payload;
1745 /* search for marker codes */
1746 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03001747 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03001748 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03001749 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03001750 case S2255_MARKER_FRAME:
sensoray-devf5402002014-01-29 15:24:07 -03001751 dprintk(dev, 4, "marker @ offset: %d [%x %x]\n",
1752 jj, pdata[0], pdata[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001753 offset = jj + PREFIX_SIZE;
1754 bframe = 1;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001755 cc = le32_to_cpu(pdword[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001756 if (cc >= MAX_CHANNELS) {
sensoray-devf5402002014-01-29 15:24:07 -03001757 dprintk(dev, 0,
1758 "bad channel\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001759 return -EINVAL;
1760 }
1761 /* reverse it */
1762 dev->cc = G_chnmap[cc];
Dean Anderson5e950fa2014-02-04 18:16:24 -03001763 vc = &dev->vc[dev->cc];
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001764 payload = le32_to_cpu(pdword[3]);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001765 if (payload > vc->req_image_size) {
1766 vc->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03001767 /* discard the bad frame */
1768 return -EINVAL;
1769 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001770 vc->pkt_size = payload;
1771 vc->jpg_size = le32_to_cpu(pdword[4]);
Dean Anderson14d96262008-08-25 13:58:55 -03001772 break;
1773 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001774
Dean Anderson14d96262008-08-25 13:58:55 -03001775 pdata += DEF_USB_BLOCK;
1776 jj += DEF_USB_BLOCK;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001777 if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001778 break;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001779 cc = G_chnmap[le32_to_cpu(pdword[1])];
Roel Kluinf14a2972009-10-23 07:59:42 -03001780 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001781 break;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001782 vc = &dev->vc[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03001783 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03001784 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03001785 /* check if channel valid */
1786 /* set mode ready */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001787 vc->setmode_ready = 1;
1788 wake_up(&vc->wait_setmode);
sensoray-devf5402002014-01-29 15:24:07 -03001789 dprintk(dev, 5, "setmode rdy %d\n", cc);
Dean Anderson14d96262008-08-25 13:58:55 -03001790 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03001791 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03001792 dev->chn_ready |= (1 << cc);
1793 if ((dev->chn_ready & 0x0f) != 0x0f)
1794 break;
1795 /* all channels ready */
sensoray-devf5402002014-01-29 15:24:07 -03001796 pr_info("s2255: fw loaded\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001797 atomic_set(&dev->fw_data->fw_state,
1798 S2255_FW_SUCCESS);
1799 wake_up(&dev->fw_data->wait_fw);
1800 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03001801 case S2255_RESPONSE_STATUS:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001802 vc->vidstatus = le32_to_cpu(pdword[3]);
1803 vc->vidstatus_ready = 1;
1804 wake_up(&vc->wait_vidstatus);
sensoray-devf5402002014-01-29 15:24:07 -03001805 dprintk(dev, 5, "vstat %x chan %d\n",
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001806 le32_to_cpu(pdword[3]), cc);
Dean Anderson4de39f52010-03-03 19:39:19 -03001807 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001808 default:
sensoray-devf5402002014-01-29 15:24:07 -03001809 pr_info("s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001810 }
1811 default:
1812 pdata++;
1813 break;
1814 }
1815 if (bframe)
1816 break;
1817 } /* for */
1818 if (!bframe)
1819 return -EINVAL;
1820 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001821 vc = &dev->vc[dev->cc];
1822 idx = vc->cur_frame;
1823 frm = &vc->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001824 /* search done. now find out if should be acquiring on this channel */
sensoray-dev340a30c2014-02-12 17:25:45 -03001825 if (!vb2_is_streaming(&vc->vb_vidq)) {
Dean Anderson14d96262008-08-25 13:58:55 -03001826 /* we found a frame, but this channel is turned off */
1827 frm->ulState = S2255_READ_IDLE;
1828 return -EINVAL;
1829 }
1830
1831 if (frm->ulState == S2255_READ_IDLE) {
1832 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03001833 frm->cur_size = 0;
1834 }
1835
Dean Anderson14d96262008-08-25 13:58:55 -03001836 /* skip the marker 512 bytes (and offset if out of sync) */
1837 psrc = (u8 *)pipe_info->transfer_buffer + offset;
1838
Dean Anderson38f993a2008-06-26 23:15:51 -03001839
1840 if (frm->lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03001841 dprintk(dev, 1, "s2255 frame buffer == NULL.%p %p %d %d",
Dean Anderson38f993a2008-06-26 23:15:51 -03001842 frm, dev, dev->cc, idx);
1843 return -ENOMEM;
1844 }
1845
1846 pdest = frm->lpvbits + frm->cur_size;
1847
Dean Anderson14d96262008-08-25 13:58:55 -03001848 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03001849
Dean Anderson5e950fa2014-02-04 18:16:24 -03001850 size = vc->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001851
Dean Anderson14d96262008-08-25 13:58:55 -03001852 /* sanity check on pdest */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001853 if ((copy_size + frm->cur_size) < vc->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03001854 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001855
Dean Anderson38f993a2008-06-26 23:15:51 -03001856 frm->cur_size += copy_size;
sensoray-devf5402002014-01-29 15:24:07 -03001857 dprintk(dev, 4, "cur_size: %lu, size: %lu\n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001858
Dean Anderson14d96262008-08-25 13:58:55 -03001859 if (frm->cur_size >= size) {
sensoray-devf5402002014-01-29 15:24:07 -03001860 dprintk(dev, 2, "******[%d]Buffer[%d]full*******\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001861 dev->cc, idx);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001862 vc->last_frame = vc->cur_frame;
1863 vc->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03001864 /* end of system frame ring buffer, start at zero */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001865 if ((vc->cur_frame == SYS_FRAMES) ||
1866 (vc->cur_frame == vc->buffer.dwFrames))
1867 vc->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001868 /* frame ready */
sensoray-dev340a30c2014-02-12 17:25:45 -03001869 if (vb2_is_streaming(&vc->vb_vidq))
Dean Anderson5e950fa2014-02-04 18:16:24 -03001870 s2255_got_frame(vc, vc->jpg_size);
1871 vc->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03001872 frm->ulState = S2255_READ_IDLE;
1873 frm->cur_size = 0;
1874
Dean Anderson38f993a2008-06-26 23:15:51 -03001875 }
1876 /* done successfully */
1877 return 0;
1878}
1879
1880static void s2255_read_video_callback(struct s2255_dev *dev,
1881 struct s2255_pipeinfo *pipe_info)
1882{
1883 int res;
sensoray-devf5402002014-01-29 15:24:07 -03001884 dprintk(dev, 50, "callback read video\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001885
1886 if (dev->cc >= MAX_CHANNELS) {
1887 dev->cc = 0;
1888 dev_err(&dev->udev->dev, "invalid channel\n");
1889 return;
1890 }
1891 /* otherwise copy to the system buffers */
1892 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03001893 if (res != 0)
sensoray-devf5402002014-01-29 15:24:07 -03001894 dprintk(dev, 4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001895
sensoray-devf5402002014-01-29 15:24:07 -03001896 dprintk(dev, 50, "callback read video done\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001897 return;
1898}
1899
1900static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
1901 u16 Index, u16 Value, void *TransferBuffer,
1902 s32 TransferBufferLength, int bOut)
1903{
1904 int r;
1905 if (!bOut) {
1906 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
1907 Request,
1908 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
1909 USB_DIR_IN,
1910 Value, Index, TransferBuffer,
1911 TransferBufferLength, HZ * 5);
1912 } else {
1913 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
1914 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1915 Value, Index, TransferBuffer,
1916 TransferBufferLength, HZ * 5);
1917 }
1918 return r;
1919}
1920
1921/*
1922 * retrieve FX2 firmware version. future use.
1923 * @param dev pointer to device extension
1924 * @return -1 for fail, else returns firmware version as an int(16 bits)
1925 */
1926static int s2255_get_fx2fw(struct s2255_dev *dev)
1927{
1928 int fw;
1929 int ret;
1930 unsigned char transBuffer[64];
1931 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
1932 S2255_VR_IN);
1933 if (ret < 0)
sensoray-devf5402002014-01-29 15:24:07 -03001934 dprintk(dev, 2, "get fw error: %x\n", ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001935 fw = transBuffer[0] + (transBuffer[1] << 8);
sensoray-devf5402002014-01-29 15:24:07 -03001936 dprintk(dev, 2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
Dean Anderson38f993a2008-06-26 23:15:51 -03001937 return fw;
1938}
1939
1940/*
1941 * Create the system ring buffer to copy frames into from the
1942 * usb read pipe.
1943 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001944static int s2255_create_sys_buffers(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03001945{
1946 unsigned long i;
1947 unsigned long reqsize;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001948 vc->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03001949 /* always allocate maximum size(PAL) for system buffers */
1950 reqsize = SYS_FRAMES_MAXSIZE;
1951
1952 if (reqsize > SYS_FRAMES_MAXSIZE)
1953 reqsize = SYS_FRAMES_MAXSIZE;
1954
1955 for (i = 0; i < SYS_FRAMES; i++) {
1956 /* allocate the frames */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001957 vc->buffer.frame[i].lpvbits = vmalloc(reqsize);
1958 vc->buffer.frame[i].size = reqsize;
1959 if (vc->buffer.frame[i].lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03001960 pr_info("out of memory. using less frames\n");
Dean Anderson5e950fa2014-02-04 18:16:24 -03001961 vc->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03001962 break;
1963 }
1964 }
1965
1966 /* make sure internal states are set */
1967 for (i = 0; i < SYS_FRAMES; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001968 vc->buffer.frame[i].ulState = 0;
1969 vc->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001970 }
1971
Dean Anderson5e950fa2014-02-04 18:16:24 -03001972 vc->cur_frame = 0;
1973 vc->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03001974 return 0;
1975}
1976
Dean Anderson5e950fa2014-02-04 18:16:24 -03001977static int s2255_release_sys_buffers(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03001978{
1979 unsigned long i;
Dean Anderson38f993a2008-06-26 23:15:51 -03001980 for (i = 0; i < SYS_FRAMES; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001981 if (vc->buffer.frame[i].lpvbits)
1982 vfree(vc->buffer.frame[i].lpvbits);
1983 vc->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001984 }
1985 return 0;
1986}
1987
1988static int s2255_board_init(struct s2255_dev *dev)
1989{
Dean Anderson38f993a2008-06-26 23:15:51 -03001990 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
1991 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03001992 int j;
1993 struct s2255_pipeinfo *pipe = &dev->pipe;
sensoray-devf5402002014-01-29 15:24:07 -03001994 dprintk(dev, 4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03001995 memset(pipe, 0, sizeof(*pipe));
1996 pipe->dev = dev;
1997 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
1998 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001999
Dean Andersonab85c6a2010-04-08 23:39:12 -03002000 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2001 GFP_KERNEL);
2002 if (pipe->transfer_buffer == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03002003 dprintk(dev, 1, "out of memory!\n");
Dean Andersonab85c6a2010-04-08 23:39:12 -03002004 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002005 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002006 /* query the firmware */
2007 fw_ver = s2255_get_fx2fw(dev);
2008
sensoray-devf5402002014-01-29 15:24:07 -03002009 pr_info("s2255: usb firmware version %d.%d\n",
2010 (fw_ver >> 8) & 0xff,
2011 fw_ver & 0xff);
Dean Andersonabce21f2009-04-23 16:04:41 -03002012
2013 if (fw_ver < S2255_CUR_USB_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002014 pr_info("s2255: newer USB firmware available\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002015
2016 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002017 struct s2255_vc *vc = &dev->vc[j];
Dean Anderson5e950fa2014-02-04 18:16:24 -03002018 vc->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002019 if (dev->pid == 0x2257 && j > 1)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002020 vc->mode.color |= (1 << 16);
2021 vc->jpegqual = S2255_DEF_JPEG_QUAL;
2022 vc->width = LINE_SZ_4CIFS_NTSC;
2023 vc->height = NUM_LINES_4CIFS_NTSC * 2;
2024 vc->std = V4L2_STD_NTSC_M;
2025 vc->fmt = &formats[0];
2026 vc->mode.restart = 1;
2027 vc->req_image_size = get_transfer_size(&mode_def);
2028 vc->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002029 /* create the system buffers */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002030 s2255_create_sys_buffers(vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03002031 }
2032 /* start read pipe */
2033 s2255_start_readpipe(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002034 dprintk(dev, 1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002035 return 0;
2036}
2037
2038static int s2255_board_shutdown(struct s2255_dev *dev)
2039{
2040 u32 i;
sensoray-devf5402002014-01-29 15:24:07 -03002041 dprintk(dev, 1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002042
2043 for (i = 0; i < MAX_CHANNELS; i++) {
sensoray-dev340a30c2014-02-12 17:25:45 -03002044 if (vb2_is_streaming(&dev->vc[i].vb_vidq))
Dean Anderson5e950fa2014-02-04 18:16:24 -03002045 s2255_stop_acquire(&dev->vc[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002046 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002047 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002048 for (i = 0; i < MAX_CHANNELS; i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002049 s2255_release_sys_buffers(&dev->vc[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002050 /* release transfer buffer */
2051 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002052 return 0;
2053}
2054
2055static void read_pipe_completion(struct urb *purb)
2056{
2057 struct s2255_pipeinfo *pipe_info;
2058 struct s2255_dev *dev;
2059 int status;
2060 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002061 pipe_info = purb->context;
Dean Anderson38f993a2008-06-26 23:15:51 -03002062 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002063 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002064 return;
2065 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002066 dev = pipe_info->dev;
2067 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002068 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002069 return;
2070 }
2071 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002072 /* if shutting down, do not resubmit, exit immediately */
2073 if (status == -ESHUTDOWN) {
sensoray-devf5402002014-01-29 15:24:07 -03002074 dprintk(dev, 2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002075 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002076 return;
2077 }
2078
2079 if (pipe_info->state == 0) {
sensoray-devf5402002014-01-29 15:24:07 -03002080 dprintk(dev, 2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002081 return;
2082 }
2083
Dean Andersonb02064c2009-04-30 12:29:38 -03002084 if (status == 0)
2085 s2255_read_video_callback(dev, pipe_info);
2086 else {
2087 pipe_info->err_count++;
sensoray-devf5402002014-01-29 15:24:07 -03002088 dprintk(dev, 1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002089 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002090
Dean Anderson38f993a2008-06-26 23:15:51 -03002091 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2092 /* reuse urb */
2093 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2094 pipe,
2095 pipe_info->transfer_buffer,
2096 pipe_info->cur_transfer_size,
2097 read_pipe_completion, pipe_info);
2098
2099 if (pipe_info->state != 0) {
sensoray-devf5402002014-01-29 15:24:07 -03002100 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC))
Dean Anderson38f993a2008-06-26 23:15:51 -03002101 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002102 } else {
sensoray-devf5402002014-01-29 15:24:07 -03002103 dprintk(dev, 2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002104 }
2105 return;
2106}
2107
2108static int s2255_start_readpipe(struct s2255_dev *dev)
2109{
2110 int pipe;
2111 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002112 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002113 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
sensoray-devf5402002014-01-29 15:24:07 -03002114 dprintk(dev, 2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002115 pipe_info->state = 1;
2116 pipe_info->err_count = 0;
2117 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2118 if (!pipe_info->stream_urb) {
2119 dev_err(&dev->udev->dev,
2120 "ReadStream: Unable to alloc URB\n");
2121 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002122 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002123 /* transfer buffer allocated in board_init */
2124 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2125 pipe,
2126 pipe_info->transfer_buffer,
2127 pipe_info->cur_transfer_size,
2128 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002129 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2130 if (retval) {
sensoray-devf5402002014-01-29 15:24:07 -03002131 pr_err("s2255: start read pipe failed\n");
Dean Andersonab85c6a2010-04-08 23:39:12 -03002132 return retval;
2133 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002134 return 0;
2135}
2136
2137/* starts acquisition process */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002138static int s2255_start_acquire(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03002139{
Dean Anderson38f993a2008-06-26 23:15:51 -03002140 int res;
2141 unsigned long chn_rev;
2142 int j;
Dean Anderson5e950fa2014-02-04 18:16:24 -03002143 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03002144 __le32 *buffer = dev->cmdbuf;
Dean Anderson38f993a2008-06-26 23:15:51 -03002145
Dean Anderson47d8c882014-02-05 15:43:51 -03002146 mutex_lock(&dev->cmdlock);
2147 chn_rev = G_chnmap[vc->idx];
Dean Anderson5e950fa2014-02-04 18:16:24 -03002148 vc->last_frame = -1;
2149 vc->bad_payload = 0;
2150 vc->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002151 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002152 vc->buffer.frame[j].ulState = 0;
2153 vc->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002154 }
2155
2156 /* send the start command */
Dean Anderson47d8c882014-02-05 15:43:51 -03002157 buffer[0] = IN_DATA_TOKEN;
2158 buffer[1] = (__le32) cpu_to_le32(chn_rev);
2159 buffer[2] = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002160 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2161 if (res != 0)
2162 dev_err(&dev->udev->dev, "CMD_START error\n");
2163
Dean Anderson5e950fa2014-02-04 18:16:24 -03002164 dprintk(dev, 2, "start acquire exit[%d] %d\n", vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03002165 mutex_unlock(&dev->cmdlock);
Dean Anderson6a5b63b2014-02-05 15:58:20 -03002166 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002167}
2168
Dean Anderson5e950fa2014-02-04 18:16:24 -03002169static int s2255_stop_acquire(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03002170{
Dean Anderson38f993a2008-06-26 23:15:51 -03002171 int res;
2172 unsigned long chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03002173 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03002174 __le32 *buffer = dev->cmdbuf;
2175
2176 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03002177 chn_rev = G_chnmap[vc->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002178 /* send the stop command */
Dean Anderson47d8c882014-02-05 15:43:51 -03002179 buffer[0] = IN_DATA_TOKEN;
2180 buffer[1] = (__le32) cpu_to_le32(chn_rev);
2181 buffer[2] = CMD_STOP;
2182
Dean Anderson38f993a2008-06-26 23:15:51 -03002183 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002184 if (res != 0)
2185 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson47d8c882014-02-05 15:43:51 -03002186
Dean Anderson5e950fa2014-02-04 18:16:24 -03002187 dprintk(dev, 4, "%s: chn %d, res %d\n", __func__, vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03002188 mutex_unlock(&dev->cmdlock);
Dean Anderson14d96262008-08-25 13:58:55 -03002189 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002190}
2191
2192static void s2255_stop_readpipe(struct s2255_dev *dev)
2193{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002194 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002195
Dean Andersonab85c6a2010-04-08 23:39:12 -03002196 pipe->state = 0;
2197 if (pipe->stream_urb) {
2198 /* cancel urb */
2199 usb_kill_urb(pipe->stream_urb);
2200 usb_free_urb(pipe->stream_urb);
2201 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002202 }
sensoray-devf5402002014-01-29 15:24:07 -03002203 dprintk(dev, 4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002204 return;
2205}
2206
Dean Anderson14d96262008-08-25 13:58:55 -03002207static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002208{
Dean Anderson14d96262008-08-25 13:58:55 -03002209 if (reset)
2210 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002211 dev->fw_data->fw_size = dev->fw_data->fw->size;
2212 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2213 memcpy(dev->fw_data->pfw_data,
2214 dev->fw_data->fw->data, CHUNK_SIZE);
2215 dev->fw_data->fw_loaded = CHUNK_SIZE;
2216 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2217 usb_sndbulkpipe(dev->udev, 2),
2218 dev->fw_data->pfw_data,
2219 CHUNK_SIZE, s2255_fwchunk_complete,
2220 dev->fw_data);
2221 mod_timer(&dev->timer, jiffies + HZ);
2222}
2223
2224/* standard usb probe function */
2225static int s2255_probe(struct usb_interface *interface,
2226 const struct usb_device_id *id)
2227{
2228 struct s2255_dev *dev = NULL;
2229 struct usb_host_interface *iface_desc;
2230 struct usb_endpoint_descriptor *endpoint;
2231 int i;
2232 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002233 __le32 *pdata;
2234 int fw_size;
Dean Anderson47d8c882014-02-05 15:43:51 -03002235
Dean Anderson38f993a2008-06-26 23:15:51 -03002236 /* allocate memory for our device state and initialize it to zero */
2237 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2238 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002239 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002240 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002241 }
Dean Anderson47d8c882014-02-05 15:43:51 -03002242
2243 dev->cmdbuf = kzalloc(S2255_CMDBUF_SIZE, GFP_KERNEL);
2244 if (dev->cmdbuf == NULL) {
2245 s2255_dev_err(&interface->dev, "out of memory\n");
2246 return -ENOMEM;
2247 }
2248
Dean Andersonfe85ce92010-06-01 19:12:07 -03002249 atomic_set(&dev->num_channels, 0);
Hans Verkuil0b84caa2013-02-26 14:14:19 -03002250 dev->pid = le16_to_cpu(id->idProduct);
Dean Anderson38f993a2008-06-26 23:15:51 -03002251 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2252 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002253 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002254 mutex_init(&dev->lock);
Dean Anderson47d8c882014-02-05 15:43:51 -03002255 mutex_init(&dev->cmdlock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002256 /* grab usb_device and save it */
2257 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2258 if (dev->udev == NULL) {
2259 dev_err(&interface->dev, "null usb device\n");
2260 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002261 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002262 }
sensoray-devf5402002014-01-29 15:24:07 -03002263 dev_dbg(&interface->dev, "dev: %p, udev %p interface %p\n",
2264 dev, dev->udev, interface);
Dean Anderson38f993a2008-06-26 23:15:51 -03002265 dev->interface = interface;
2266 /* set up the endpoint information */
2267 iface_desc = interface->cur_altsetting;
sensoray-devf5402002014-01-29 15:24:07 -03002268 dev_dbg(&interface->dev, "num EP: %d\n",
2269 iface_desc->desc.bNumEndpoints);
Dean Anderson38f993a2008-06-26 23:15:51 -03002270 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2271 endpoint = &iface_desc->endpoint[i].desc;
2272 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2273 /* we found the bulk in endpoint */
2274 dev->read_endpoint = endpoint->bEndpointAddress;
2275 }
2276 }
2277
2278 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002279 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002280 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002281 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002282 init_timer(&dev->timer);
2283 dev->timer.function = s2255_timer;
2284 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002285 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002286 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002287 struct s2255_vc *vc = &dev->vc[i];
2288 vc->idx = i;
2289 vc->dev = dev;
2290 init_waitqueue_head(&vc->wait_setmode);
2291 init_waitqueue_head(&vc->wait_vidstatus);
sensoray-dev340a30c2014-02-12 17:25:45 -03002292 spin_lock_init(&vc->qlock);
2293 mutex_init(&vc->vb_lock);
Dean Anderson4de39f52010-03-03 19:39:19 -03002294 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002295
2296 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002297 if (!dev->fw_data->fw_urb) {
2298 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002299 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002300 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002301
Dean Anderson38f993a2008-06-26 23:15:51 -03002302 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2303 if (!dev->fw_data->pfw_data) {
2304 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002305 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002306 }
2307 /* load the first chunk */
2308 if (request_firmware(&dev->fw_data->fw,
2309 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
sensoray-devf5402002014-01-29 15:24:07 -03002310 dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002311 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002312 }
Dean Anderson14d96262008-08-25 13:58:55 -03002313 /* check the firmware is valid */
2314 fw_size = dev->fw_data->fw->size;
2315 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002316
Dean Anderson14d96262008-08-25 13:58:55 -03002317 if (*pdata != S2255_FW_MARKER) {
sensoray-devf5402002014-01-29 15:24:07 -03002318 dev_err(&interface->dev, "Firmware invalid.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002319 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002320 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002321 } else {
2322 /* make sure firmware is the latest */
2323 __le32 *pRel;
2324 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
sensoray-devf5402002014-01-29 15:24:07 -03002325 pr_info("s2255 dsp fw version %x\n", le32_to_cpu(*pRel));
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002326 dev->dsp_fw_ver = le32_to_cpu(*pRel);
2327 if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002328 pr_info("s2255: f2255usb.bin out of date.\n");
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002329 if (dev->pid == 0x2257 &&
2330 dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
sensoray-devf5402002014-01-29 15:24:07 -03002331 pr_warn("2257 needs firmware %d or above.\n",
2332 S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002333 }
Dean Anderson14d96262008-08-25 13:58:55 -03002334 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002335 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002336 retval = s2255_board_init(dev);
2337 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002338 goto errorBOARDINIT;
Dean Anderson14d96262008-08-25 13:58:55 -03002339 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002340 /* loads v4l specific */
2341 retval = s2255_probe_v4l(dev);
2342 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002343 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002344 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2345 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002346errorBOARDINIT:
2347 s2255_board_shutdown(dev);
2348errorFWMARKER:
2349 release_firmware(dev->fw_data->fw);
2350errorREQFW:
2351 kfree(dev->fw_data->pfw_data);
2352errorFWDATA2:
2353 usb_free_urb(dev->fw_data->fw_urb);
2354errorFWURB:
2355 del_timer(&dev->timer);
2356errorEP:
2357 usb_put_dev(dev->udev);
2358errorUDEV:
2359 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002360 mutex_destroy(&dev->lock);
2361errorFWDATA1:
Dean Anderson47d8c882014-02-05 15:43:51 -03002362 kfree(dev->cmdbuf);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002363 kfree(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002364 pr_warn("Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002365 return retval;
2366}
2367
2368/* disconnect routine. when board is removed physically or with rmmod */
2369static void s2255_disconnect(struct usb_interface *interface)
2370{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002371 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002372 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002373 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002374 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002375 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002376 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002377 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002378 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002379 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002380 for (i = 0; i < channels; i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002381 video_unregister_device(&dev->vc[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002382 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002383 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2384 wake_up(&dev->fw_data->wait_fw);
2385 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002386 dev->vc[i].setmode_ready = 1;
2387 wake_up(&dev->vc[i].wait_setmode);
2388 dev->vc[i].vidstatus_ready = 1;
2389 wake_up(&dev->vc[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002390 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002391 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002392 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002393 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002394}
2395
2396static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002397 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002398 .probe = s2255_probe,
2399 .disconnect = s2255_disconnect,
2400 .id_table = s2255_table,
2401};
2402
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002403module_usb_driver(s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002404
2405MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2406MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2407MODULE_LICENSE("GPL");
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03002408MODULE_VERSION(S2255_VERSION);
Tim Gardner1bec9822012-07-24 16:52:27 -03002409MODULE_FIRMWARE(FIRMWARE_FILE_NAME);