blob: 0f3c34d47ec3f1063928aafab20d6fc2b56d1882 [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
sensoray-dev9694fbe2014-11-04 17:34:03 -0300561static void 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;
sensoray-dev9694fbe2014-11-04 17:34:03 -0300566
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");
sensoray-dev9694fbe2014-11-04 17:34:03 -0300570 spin_unlock_irqrestore(&vc->qlock, flags);
571 return;
Dean Anderson38f993a2008-06-26 23:15:51 -0300572 }
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);
sensoray-dev9694fbe2014-11-04 17:34:03 -0300577 buf->vb.v4l2_buf.field = vc->field;
578 buf->vb.v4l2_buf.sequence = vc->frame_count;
sensoray-dev340a30c2014-02-12 17:25:45 -0300579 spin_unlock_irqrestore(&vc->qlock, flags);
sensoray-dev9694fbe2014-11-04 17:34:03 -0300580
581 s2255_fillbuff(vc, buf, jpgsize);
582 /* tell v4l buffer was filled */
583 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
584 dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf);
Dean Anderson38f993a2008-06-26 23:15:51 -0300585}
586
Dean Anderson38f993a2008-06-26 23:15:51 -0300587static const struct s2255_fmt *format_by_fourcc(int fourcc)
588{
589 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300590 for (i = 0; i < ARRAY_SIZE(formats); i++) {
591 if (-1 == formats[i].fourcc)
592 continue;
sensoray-devf5402002014-01-29 15:24:07 -0300593 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
594 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
595 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300596 if (formats[i].fourcc == fourcc)
597 return formats + i;
598 }
599 return NULL;
600}
601
Dean Anderson38f993a2008-06-26 23:15:51 -0300602/* video buffer vmalloc implementation based partly on VIVI driver which is
603 * Copyright (c) 2006 by
604 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
605 * Ted Walther <ted--a.t--enumera.com>
606 * John Sokol <sokol--a.t--videotechnology.com>
607 * http://v4l.videotechnology.com/
608 *
609 */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300610static void s2255_fillbuff(struct s2255_vc *vc,
Dean Andersonfe85ce92010-06-01 19:12:07 -0300611 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300612{
613 int pos = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300614 const char *tmpbuf;
sensoray-dev340a30c2014-02-12 17:25:45 -0300615 char *vbuf = vb2_plane_vaddr(&buf->vb, 0);
Dean Anderson38f993a2008-06-26 23:15:51 -0300616 unsigned long last_frame;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300617 struct s2255_dev *dev = vc->dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300618
619 if (!vbuf)
620 return;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300621 last_frame = vc->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300622 if (last_frame != -1) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300623 tmpbuf =
Dean Anderson5e950fa2014-02-04 18:16:24 -0300624 (const char *)vc->buffer.frame[last_frame].lpvbits;
Dean Anderson8bf405a2014-02-05 15:18:55 -0300625 switch (vc->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300626 case V4L2_PIX_FMT_YUYV:
627 case V4L2_PIX_FMT_UYVY:
628 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
sensoray-dev340a30c2014-02-12 17:25:45 -0300629 vbuf, vc->width,
630 vc->height,
Dean Anderson8bf405a2014-02-05 15:18:55 -0300631 vc->fmt->fourcc);
Dean Anderson38f993a2008-06-26 23:15:51 -0300632 break;
633 case V4L2_PIX_FMT_GREY:
sensoray-dev340a30c2014-02-12 17:25:45 -0300634 memcpy(vbuf, tmpbuf, vc->width * vc->height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300635 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300636 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300637 case V4L2_PIX_FMT_MJPEG:
sensoray-dev1f391212014-11-17 19:50:36 -0300638 vb2_set_plane_payload(&buf->vb, 0, jpgsize);
sensoray-dev340a30c2014-02-12 17:25:45 -0300639 memcpy(vbuf, tmpbuf, jpgsize);
Dean Anderson14d96262008-08-25 13:58:55 -0300640 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300641 case V4L2_PIX_FMT_YUV422P:
642 memcpy(vbuf, tmpbuf,
sensoray-dev340a30c2014-02-12 17:25:45 -0300643 vc->width * vc->height * 2);
Dean Anderson38f993a2008-06-26 23:15:51 -0300644 break;
645 default:
sensoray-devf5402002014-01-29 15:24:07 -0300646 pr_info("s2255: unknown format?\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300647 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300648 vc->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300649 } else {
sensoray-devf5402002014-01-29 15:24:07 -0300650 pr_err("s2255: =======no frame\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300651 return;
Dean Anderson38f993a2008-06-26 23:15:51 -0300652 }
sensoray-devf5402002014-01-29 15:24:07 -0300653 dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n",
Dean Anderson38f993a2008-06-26 23:15:51 -0300654 (unsigned long)vbuf, pos);
Dean Anderson38f993a2008-06-26 23:15:51 -0300655}
656
657
658/* ------------------------------------------------------------------
659 Videobuf operations
660 ------------------------------------------------------------------*/
661
sensoray-dev340a30c2014-02-12 17:25:45 -0300662static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
663 unsigned int *nbuffers, unsigned int *nplanes,
664 unsigned int sizes[], void *alloc_ctxs[])
Dean Anderson38f993a2008-06-26 23:15:51 -0300665{
sensoray-dev340a30c2014-02-12 17:25:45 -0300666 struct s2255_vc *vc = vb2_get_drv_priv(vq);
Dean Anderson9da62eb2014-02-05 14:58:06 -0300667 if (*nbuffers < S2255_MIN_BUFS)
668 *nbuffers = S2255_MIN_BUFS;
sensoray-dev340a30c2014-02-12 17:25:45 -0300669 *nplanes = 1;
670 sizes[0] = vc->width * vc->height * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300671 return 0;
672}
673
sensoray-dev340a30c2014-02-12 17:25:45 -0300674static int buffer_prepare(struct vb2_buffer *vb)
Dean Anderson38f993a2008-06-26 23:15:51 -0300675{
sensoray-dev340a30c2014-02-12 17:25:45 -0300676 struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300677 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300678 int w = vc->width;
679 int h = vc->height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300680 unsigned long size;
681
682 dprintk(vc->dev, 4, "%s\n", __func__);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300683 if (vc->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300684 return -EINVAL;
685
Dean Anderson5e950fa2014-02-04 18:16:24 -0300686 if ((w < norm_minw(vc)) ||
687 (w > norm_maxw(vc)) ||
688 (h < norm_minh(vc)) ||
689 (h > norm_maxh(vc))) {
Dean Anderson92cde472014-02-05 17:38:42 -0300690 dprintk(vc->dev, 4, "invalid buffer prepare\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300691 return -EINVAL;
692 }
sensoray-dev340a30c2014-02-12 17:25:45 -0300693 size = w * h * (vc->fmt->depth >> 3);
694 if (vb2_plane_size(vb, 0) < size) {
Dean Anderson92cde472014-02-05 17:38:42 -0300695 dprintk(vc->dev, 4, "invalid buffer prepare\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300696 return -EINVAL;
697 }
698
sensoray-dev340a30c2014-02-12 17:25:45 -0300699 vb2_set_plane_payload(&buf->vb, 0, size);
Dean Anderson38f993a2008-06-26 23:15:51 -0300700 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300701}
702
sensoray-dev340a30c2014-02-12 17:25:45 -0300703static void buffer_queue(struct vb2_buffer *vb)
Dean Anderson38f993a2008-06-26 23:15:51 -0300704{
705 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
sensoray-dev340a30c2014-02-12 17:25:45 -0300706 struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
707 unsigned long flags = 0;
Dean Anderson92cde472014-02-05 17:38:42 -0300708 dprintk(vc->dev, 1, "%s\n", __func__);
sensoray-dev340a30c2014-02-12 17:25:45 -0300709 spin_lock_irqsave(&vc->qlock, flags);
710 list_add_tail(&buf->list, &vc->buf_list);
711 spin_unlock_irqrestore(&vc->qlock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300712}
713
sensoray-dev340a30c2014-02-12 17:25:45 -0300714static int start_streaming(struct vb2_queue *vq, unsigned int count);
Hans Verkuile37559b2014-04-17 02:47:21 -0300715static void stop_streaming(struct vb2_queue *vq);
Dean Anderson38f993a2008-06-26 23:15:51 -0300716
sensoray-dev340a30c2014-02-12 17:25:45 -0300717static struct vb2_ops s2255_video_qops = {
718 .queue_setup = queue_setup,
Dean Anderson38f993a2008-06-26 23:15:51 -0300719 .buf_prepare = buffer_prepare,
720 .buf_queue = buffer_queue,
sensoray-dev340a30c2014-02-12 17:25:45 -0300721 .start_streaming = start_streaming,
722 .stop_streaming = stop_streaming,
723 .wait_prepare = vb2_ops_wait_prepare,
724 .wait_finish = vb2_ops_wait_finish,
Dean Anderson38f993a2008-06-26 23:15:51 -0300725};
726
Dean Anderson38f993a2008-06-26 23:15:51 -0300727static int vidioc_querycap(struct file *file, void *priv,
728 struct v4l2_capability *cap)
729{
sensoray-dev340a30c2014-02-12 17:25:45 -0300730 struct s2255_vc *vc = video_drvdata(file);
731 struct s2255_dev *dev = vc->dev;
Hans Verkuil39696002013-02-07 07:06:21 -0300732
Dean Anderson38f993a2008-06-26 23:15:51 -0300733 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
734 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300735 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
sensoray-dev340a30c2014-02-12 17:25:45 -0300736 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
737 V4L2_CAP_READWRITE;
Hans Verkuil39696002013-02-07 07:06:21 -0300738 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300739 return 0;
740}
741
742static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
743 struct v4l2_fmtdesc *f)
744{
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300745 int index = f->index;
Dean Anderson38f993a2008-06-26 23:15:51 -0300746
747 if (index >= ARRAY_SIZE(formats))
748 return -EINVAL;
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300749 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
750 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
751 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300752 strlcpy(f->description, formats[index].name, sizeof(f->description));
753 f->pixelformat = formats[index].fourcc;
754 return 0;
755}
756
757static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
758 struct v4l2_format *f)
759{
sensoray-dev340a30c2014-02-12 17:25:45 -0300760 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300761 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300762
Dean Anderson5e950fa2014-02-04 18:16:24 -0300763 f->fmt.pix.width = vc->width;
764 f->fmt.pix.height = vc->height;
Hans Verkuil92513612013-02-15 06:05:08 -0300765 if (f->fmt.pix.height >=
766 (is_ntsc ? NUM_LINES_1CIFS_NTSC : NUM_LINES_1CIFS_PAL) * 2)
767 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
768 else
769 f->fmt.pix.field = V4L2_FIELD_TOP;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300770 f->fmt.pix.pixelformat = vc->fmt->fourcc;
771 f->fmt.pix.bytesperline = f->fmt.pix.width * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300772 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300773 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
774 f->fmt.pix.priv = 0;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300775 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300776}
777
778static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
779 struct v4l2_format *f)
780{
781 const struct s2255_fmt *fmt;
782 enum v4l2_field field;
sensoray-dev340a30c2014-02-12 17:25:45 -0300783 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300784 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300785
786 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
787
788 if (fmt == NULL)
789 return -EINVAL;
790
791 field = f->fmt.pix.field;
Dean Anderson38f993a2008-06-26 23:15:51 -0300792
Dean Anderson92cde472014-02-05 17:38:42 -0300793 dprintk(vc->dev, 50, "%s NTSC: %d suggested width: %d, height: %d\n",
Dean Anderson85b85482010-04-08 23:51:17 -0300794 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300795 if (is_ntsc) {
796 /* NTSC */
797 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
798 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300799 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300800 } else {
801 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
Hans Verkuil92513612013-02-15 06:05:08 -0300802 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300803 }
804 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
805 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
806 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
807 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
808 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
809 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
810 else
811 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
812 } else {
813 /* PAL */
814 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
815 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300816 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300817 } else {
818 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300819 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300820 }
Hans Verkuil92513612013-02-15 06:05:08 -0300821 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300822 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300823 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300824 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300825 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300826 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300827 else
Dean Anderson38f993a2008-06-26 23:15:51 -0300828 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300829 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300830 f->fmt.pix.field = field;
831 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
832 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300833 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
834 f->fmt.pix.priv = 0;
Dean Anderson92cde472014-02-05 17:38:42 -0300835 dprintk(vc->dev, 50, "%s: set width %d height %d field %d\n", __func__,
Dean Anderson85b85482010-04-08 23:51:17 -0300836 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300837 return 0;
838}
839
840static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
841 struct v4l2_format *f)
842{
sensoray-dev340a30c2014-02-12 17:25:45 -0300843 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson38f993a2008-06-26 23:15:51 -0300844 const struct s2255_fmt *fmt;
sensoray-dev340a30c2014-02-12 17:25:45 -0300845 struct vb2_queue *q = &vc->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300846 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300847 int ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300848
sensoray-dev340a30c2014-02-12 17:25:45 -0300849 ret = vidioc_try_fmt_vid_cap(file, vc, f);
Dean Anderson38f993a2008-06-26 23:15:51 -0300850
851 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300852 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300853
854 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
855
856 if (fmt == NULL)
857 return -EINVAL;
858
sensoray-dev340a30c2014-02-12 17:25:45 -0300859 if (vb2_is_busy(q)) {
Dean Anderson92cde472014-02-05 17:38:42 -0300860 dprintk(vc->dev, 1, "queue busy\n");
sensoray-dev340a30c2014-02-12 17:25:45 -0300861 return -EBUSY;
Dean Anderson38f993a2008-06-26 23:15:51 -0300862 }
863
Dean Anderson5e950fa2014-02-04 18:16:24 -0300864 mode = vc->mode;
865 vc->fmt = fmt;
866 vc->width = f->fmt.pix.width;
867 vc->height = f->fmt.pix.height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300868 vc->field = f->fmt.pix.field;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300869 if (vc->width > norm_minw(vc)) {
870 if (vc->height > norm_minh(vc)) {
871 if (vc->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -0300872 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300873 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -0300874 else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300875 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -0300876 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300877 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300878
879 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300880 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300881 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300882 /* color mode */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300883 switch (vc->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300884 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300885 mode.color &= ~MASK_COLOR;
886 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -0300887 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300888 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300889 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300890 mode.color &= ~MASK_COLOR;
891 mode.color |= COLOR_JPG;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300892 mode.color |= (vc->jpegqual << 8);
Dean Anderson14d96262008-08-25 13:58:55 -0300893 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300894 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300895 mode.color &= ~MASK_COLOR;
896 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300897 break;
898 case V4L2_PIX_FMT_YUYV:
899 case V4L2_PIX_FMT_UYVY:
900 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300901 mode.color &= ~MASK_COLOR;
902 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -0300903 break;
904 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300905 if ((mode.color & MASK_COLOR) != (vc->mode.color & MASK_COLOR))
Dean Andersonfe85ce92010-06-01 19:12:07 -0300906 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300907 else if (mode.scale != vc->mode.scale)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300908 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300909 else if (mode.format != vc->mode.format)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300910 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300911 vc->mode = mode;
912 (void) s2255_set_mode(vc, &mode);
sensoray-dev340a30c2014-02-12 17:25:45 -0300913 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300914}
915
Dean Anderson38f993a2008-06-26 23:15:51 -0300916
Dean Anderson38f993a2008-06-26 23:15:51 -0300917/* write to the configuration pipe, synchronously */
918static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
919 int size)
920{
921 int pipe;
922 int done;
923 long retval = -1;
924 if (udev) {
925 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
926 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
927 }
928 return retval;
929}
930
931static u32 get_transfer_size(struct s2255_mode *mode)
932{
933 int linesPerFrame = LINE_SZ_DEF;
934 int pixelsPerLine = NUM_LINES_DEF;
935 u32 outImageSize;
936 u32 usbInSize;
937 unsigned int mask_mult;
938
939 if (mode == NULL)
940 return 0;
941
942 if (mode->format == FORMAT_NTSC) {
943 switch (mode->scale) {
944 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -0300945 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -0300946 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
947 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
948 break;
949 case SCALE_2CIFS:
950 linesPerFrame = NUM_LINES_2CIFS_NTSC;
951 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
952 break;
953 case SCALE_1CIFS:
954 linesPerFrame = NUM_LINES_1CIFS_NTSC;
955 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
956 break;
957 default:
958 break;
959 }
960 } else if (mode->format == FORMAT_PAL) {
961 switch (mode->scale) {
962 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -0300963 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -0300964 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
965 pixelsPerLine = LINE_SZ_4CIFS_PAL;
966 break;
967 case SCALE_2CIFS:
968 linesPerFrame = NUM_LINES_2CIFS_PAL;
969 pixelsPerLine = LINE_SZ_2CIFS_PAL;
970 break;
971 case SCALE_1CIFS:
972 linesPerFrame = NUM_LINES_1CIFS_PAL;
973 pixelsPerLine = LINE_SZ_1CIFS_PAL;
974 break;
975 default:
976 break;
977 }
978 }
979 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -0300980 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300981 /* 2 bytes/pixel if not monochrome */
982 outImageSize *= 2;
983 }
984
985 /* total bytes to send including prefix and 4K padding;
986 must be a multiple of USB_READ_SIZE */
987 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
988 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
989 /* if size not a multiple of USB_READ_SIZE */
990 if (usbInSize & ~mask_mult)
991 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
992 return usbInSize;
993}
994
Dean Anderson85b85482010-04-08 23:51:17 -0300995static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -0300996{
997 struct device *dev = &sdev->udev->dev;
998 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -0300999 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1000 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001001 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001002 dev_info(dev, "------------------------------------------------\n");
1003}
1004
1005/*
1006 * set mode is the function which controls the DSP.
1007 * the restart parameter in struct s2255_mode should be set whenever
1008 * the image size could change via color format, video system or image
1009 * size.
1010 * When the restart parameter is set, we sleep for ONE frame to allow the
1011 * DSP time to get the new frame
1012 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001013static int s2255_set_mode(struct s2255_vc *vc,
Dean Anderson38f993a2008-06-26 23:15:51 -03001014 struct s2255_mode *mode)
1015{
1016 int res;
Dean Anderson38f993a2008-06-26 23:15:51 -03001017 unsigned long chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001018 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001019 int i;
Dean Anderson47d8c882014-02-05 15:43:51 -03001020 __le32 *buffer = dev->cmdbuf;
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001021
Dean Anderson47d8c882014-02-05 15:43:51 -03001022 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001023 chn_rev = G_chnmap[vc->idx];
1024 dprintk(dev, 3, "%s channel: %d\n", __func__, vc->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001025 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001026 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1027 mode->color &= ~MASK_COLOR;
1028 mode->color |= COLOR_JPG;
1029 mode->color &= ~MASK_JPG_QUALITY;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001030 mode->color |= (vc->jpegqual << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001031 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001032 /* save the mode */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001033 vc->mode = *mode;
1034 vc->req_image_size = get_transfer_size(mode);
1035 dprintk(dev, 1, "%s: reqsize %ld\n", __func__, vc->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001036 /* set the mode */
1037 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001038 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001039 buffer[2] = CMD_SET_MODE;
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001040 for (i = 0; i < sizeof(struct s2255_mode) / sizeof(u32); i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001041 buffer[3 + i] = cpu_to_le32(((u32 *)&vc->mode)[i]);
1042 vc->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001043 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1044 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001045 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001046 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001047 if (mode->restart) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001048 wait_event_timeout(vc->wait_setmode,
1049 (vc->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001050 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001051 if (vc->setmode_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001052 dprintk(dev, 0, "s2255: no set mode response\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001053 res = -EFAULT;
1054 }
1055 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001056 /* clear the restart flag */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001057 vc->mode.restart = 0;
1058 dprintk(dev, 1, "%s chn %d, result: %d\n", __func__, vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03001059 mutex_unlock(&dev->cmdlock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001060 return res;
1061}
1062
Dean Anderson5e950fa2014-02-04 18:16:24 -03001063static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001064{
1065 int res;
Dean Anderson4de39f52010-03-03 19:39:19 -03001066 u32 chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001067 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03001068 __le32 *buffer = dev->cmdbuf;
1069
1070 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001071 chn_rev = G_chnmap[vc->idx];
1072 dprintk(dev, 4, "%s chan %d\n", __func__, vc->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001073 /* form the get vid status command */
1074 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001075 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001076 buffer[2] = CMD_STATUS;
1077 *pstatus = 0;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001078 vc->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001079 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001080 wait_event_timeout(vc->wait_vidstatus,
1081 (vc->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001082 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001083 if (vc->vidstatus_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001084 dprintk(dev, 0, "s2255: no vidstatus response\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001085 res = -EFAULT;
1086 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001087 *pstatus = vc->vidstatus;
sensoray-devf5402002014-01-29 15:24:07 -03001088 dprintk(dev, 4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson47d8c882014-02-05 15:43:51 -03001089 mutex_unlock(&dev->cmdlock);
Dean Anderson4de39f52010-03-03 19:39:19 -03001090 return res;
1091}
1092
sensoray-dev340a30c2014-02-12 17:25:45 -03001093static int start_streaming(struct vb2_queue *vq, unsigned int count)
Dean Anderson38f993a2008-06-26 23:15:51 -03001094{
sensoray-dev340a30c2014-02-12 17:25:45 -03001095 struct s2255_vc *vc = vb2_get_drv_priv(vq);
Dean Anderson38f993a2008-06-26 23:15:51 -03001096 int j;
Dean Anderson92cde472014-02-05 17:38:42 -03001097
Dean Anderson5e950fa2014-02-04 18:16:24 -03001098 vc->last_frame = -1;
1099 vc->bad_payload = 0;
1100 vc->cur_frame = 0;
1101 vc->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001102 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001103 vc->buffer.frame[j].ulState = S2255_READ_IDLE;
1104 vc->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001105 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001106 return s2255_start_acquire(vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03001107}
1108
sensoray-dev340a30c2014-02-12 17:25:45 -03001109/* abort streaming and wait for last buffer */
Hans Verkuile37559b2014-04-17 02:47:21 -03001110static void stop_streaming(struct vb2_queue *vq)
Dean Anderson38f993a2008-06-26 23:15:51 -03001111{
sensoray-dev340a30c2014-02-12 17:25:45 -03001112 struct s2255_vc *vc = vb2_get_drv_priv(vq);
1113 struct s2255_buffer *buf, *node;
1114 unsigned long flags;
1115 (void) s2255_stop_acquire(vc);
1116 spin_lock_irqsave(&vc->qlock, flags);
1117 list_for_each_entry_safe(buf, node, &vc->buf_list, list) {
1118 list_del(&buf->list);
1119 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
1120 dprintk(vc->dev, 2, "[%p/%d] done\n",
1121 buf, buf->vb.v4l2_buf.index);
1122 }
1123 spin_unlock_irqrestore(&vc->qlock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -03001124}
1125
Hans Verkuil314527a2013-03-15 06:10:40 -03001126static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i)
Dean Anderson38f993a2008-06-26 23:15:51 -03001127{
sensoray-dev340a30c2014-02-12 17:25:45 -03001128 struct s2255_vc *vc = video_drvdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001129 struct s2255_mode mode;
sensoray-dev340a30c2014-02-12 17:25:45 -03001130 struct vb2_queue *q = &vc->vb_vidq;
Hans Verkuil469af772013-02-15 06:12:58 -03001131
sensoray-dev340a30c2014-02-12 17:25:45 -03001132 /*
1133 * Changing the standard implies a format change, which is not allowed
1134 * while buffers for use with streaming have already been allocated.
1135 */
1136 if (vb2_is_busy(q))
1137 return -EBUSY;
1138
Dean Anderson92cde472014-02-05 17:38:42 -03001139 mode = vc->mode;
Hans Verkuil314527a2013-03-15 06:10:40 -03001140 if (i & V4L2_STD_525_60) {
Dean Anderson92cde472014-02-05 17:38:42 -03001141 dprintk(vc->dev, 4, "%s 60 Hz\n", __func__);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001142 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001143 if (mode.format != FORMAT_NTSC) {
1144 mode.restart = 1;
1145 mode.format = FORMAT_NTSC;
1146 mode.fdec = FDEC_1;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001147 vc->width = LINE_SZ_4CIFS_NTSC;
1148 vc->height = NUM_LINES_4CIFS_NTSC * 2;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001149 }
Hans Verkuil314527a2013-03-15 06:10:40 -03001150 } else if (i & V4L2_STD_625_50) {
Dean Anderson92cde472014-02-05 17:38:42 -03001151 dprintk(vc->dev, 4, "%s 50 Hz\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001152 if (mode.format != FORMAT_PAL) {
1153 mode.restart = 1;
1154 mode.format = FORMAT_PAL;
1155 mode.fdec = FDEC_1;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001156 vc->width = LINE_SZ_4CIFS_PAL;
1157 vc->height = NUM_LINES_4CIFS_PAL * 2;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001158 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001159 } else
1160 return -EINVAL;
Dean Anderson92cde472014-02-05 17:38:42 -03001161 vc->std = i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001162 if (mode.restart)
Dean Anderson92cde472014-02-05 17:38:42 -03001163 s2255_set_mode(vc, &mode);
sensoray-dev340a30c2014-02-12 17:25:45 -03001164 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001165}
1166
Hans Verkuil469af772013-02-15 06:12:58 -03001167static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *i)
1168{
sensoray-dev340a30c2014-02-12 17:25:45 -03001169 struct s2255_vc *vc = video_drvdata(file);
Hans Verkuil469af772013-02-15 06:12:58 -03001170
Dean Anderson92cde472014-02-05 17:38:42 -03001171 *i = vc->std;
Hans Verkuil469af772013-02-15 06:12:58 -03001172 return 0;
1173}
1174
Dean Anderson38f993a2008-06-26 23:15:51 -03001175/* Sensoray 2255 is a multiple channel capture device.
1176 It does not have a "crossbar" of inputs.
1177 We use one V4L device per channel. The user must
1178 be aware that certain combinations are not allowed.
1179 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1180 at once in color(you can do full fps on 4 channels with greyscale.
1181*/
1182static int vidioc_enum_input(struct file *file, void *priv,
1183 struct v4l2_input *inp)
1184{
sensoray-dev340a30c2014-02-12 17:25:45 -03001185 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson92cde472014-02-05 17:38:42 -03001186 struct s2255_dev *dev = vc->dev;
Dean Anderson4de39f52010-03-03 19:39:19 -03001187 u32 status = 0;
Dean Anderson92cde472014-02-05 17:38:42 -03001188
Dean Anderson38f993a2008-06-26 23:15:51 -03001189 if (inp->index != 0)
1190 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001191 inp->type = V4L2_INPUT_TYPE_CAMERA;
1192 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001193 inp->status = 0;
1194 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1195 int rc;
Dean Anderson92cde472014-02-05 17:38:42 -03001196 rc = s2255_cmd_status(vc, &status);
sensoray-devf5402002014-01-29 15:24:07 -03001197 dprintk(dev, 4, "s2255_cmd_status rc: %d status %x\n",
1198 rc, status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001199 if (rc == 0)
1200 inp->status = (status & 0x01) ? 0
1201 : V4L2_IN_ST_NO_SIGNAL;
1202 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001203 switch (dev->pid) {
1204 case 0x2255:
1205 default:
1206 strlcpy(inp->name, "Composite", sizeof(inp->name));
1207 break;
1208 case 0x2257:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001209 strlcpy(inp->name, (vc->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001210 sizeof(inp->name));
1211 break;
1212 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001213 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001214}
1215
1216static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1217{
1218 *i = 0;
1219 return 0;
1220}
1221static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1222{
1223 if (i > 0)
1224 return -EINVAL;
1225 return 0;
1226}
1227
Hans Verkuil192f1e72013-02-15 05:51:21 -03001228static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
Dean Anderson38f993a2008-06-26 23:15:51 -03001229{
Dean Anderson5e950fa2014-02-04 18:16:24 -03001230 struct s2255_vc *vc =
1231 container_of(ctrl->handler, struct s2255_vc, hdl);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001232 struct s2255_mode mode;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001233 mode = vc->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001234 /* update the mode to the corresponding value */
1235 switch (ctrl->id) {
1236 case V4L2_CID_BRIGHTNESS:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001237 mode.bright = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001238 break;
1239 case V4L2_CID_CONTRAST:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001240 mode.contrast = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001241 break;
1242 case V4L2_CID_HUE:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001243 mode.hue = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001244 break;
1245 case V4L2_CID_SATURATION:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001246 mode.saturation = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001247 break;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001248 case V4L2_CID_S2255_COLORFILTER:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001249 mode.color &= ~MASK_INPUT_TYPE;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001250 mode.color |= !ctrl->val << 16;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001251 break;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001252 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001253 vc->jpegqual = ctrl->val;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001254 return 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001255 default:
1256 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001257 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001258 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001259 /* set mode here. Note: stream does not need restarted.
1260 some V4L programs restart stream unnecessarily
1261 after a s_crtl.
1262 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001263 s2255_set_mode(vc, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001264 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001265}
1266
Dean Anderson22b88d42008-08-29 15:33:19 -03001267static int vidioc_g_jpegcomp(struct file *file, void *priv,
1268 struct v4l2_jpegcompression *jc)
1269{
sensoray-dev340a30c2014-02-12 17:25:45 -03001270 struct s2255_vc *vc = video_drvdata(file);
Hans Verkuil7041dec2013-02-15 05:53:45 -03001271
1272 memset(jc, 0, sizeof(*jc));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001273 jc->quality = vc->jpegqual;
Dean Anderson92cde472014-02-05 17:38:42 -03001274 dprintk(vc->dev, 2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001275 return 0;
1276}
1277
1278static int vidioc_s_jpegcomp(struct file *file, void *priv,
Hans Verkuild88aab52012-09-17 05:05:25 -03001279 const struct v4l2_jpegcompression *jc)
Dean Anderson22b88d42008-08-29 15:33:19 -03001280{
sensoray-dev340a30c2014-02-12 17:25:45 -03001281 struct s2255_vc *vc = video_drvdata(file);
1282
Dean Anderson22b88d42008-08-29 15:33:19 -03001283 if (jc->quality < 0 || jc->quality > 100)
1284 return -EINVAL;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001285 v4l2_ctrl_s_ctrl(vc->jpegqual_ctrl, jc->quality);
Dean Anderson92cde472014-02-05 17:38:42 -03001286 dprintk(vc->dev, 2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001287 return 0;
1288}
Dean Anderson7d853532009-05-15 14:32:04 -03001289
1290static int vidioc_g_parm(struct file *file, void *priv,
1291 struct v4l2_streamparm *sp)
1292{
Dean Andersone6b44bc2010-03-08 20:04:48 -03001293 __u32 def_num, def_dem;
sensoray-dev340a30c2014-02-12 17:25:45 -03001294 struct s2255_vc *vc = video_drvdata(file);
1295
Dean Anderson7d853532009-05-15 14:32:04 -03001296 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1297 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001298 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001299 sp->parm.capture.capturemode = vc->cap_parm.capturemode;
sensoray-dev340a30c2014-02-12 17:25:45 -03001300 sp->parm.capture.readbuffers = S2255_MIN_BUFS;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001301 def_num = (vc->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1302 def_dem = (vc->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001303 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001304 switch (vc->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001305 default:
1306 case FDEC_1:
1307 sp->parm.capture.timeperframe.numerator = def_num;
1308 break;
1309 case FDEC_2:
1310 sp->parm.capture.timeperframe.numerator = def_num * 2;
1311 break;
1312 case FDEC_3:
1313 sp->parm.capture.timeperframe.numerator = def_num * 3;
1314 break;
1315 case FDEC_5:
1316 sp->parm.capture.timeperframe.numerator = def_num * 5;
1317 break;
1318 }
Dean Anderson92cde472014-02-05 17:38:42 -03001319 dprintk(vc->dev, 4, "%s capture mode, %d timeperframe %d/%d\n",
sensoray-devf5402002014-01-29 15:24:07 -03001320 __func__,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001321 sp->parm.capture.capturemode,
1322 sp->parm.capture.timeperframe.numerator,
1323 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001324 return 0;
1325}
1326
1327static int vidioc_s_parm(struct file *file, void *priv,
1328 struct v4l2_streamparm *sp)
1329{
sensoray-dev340a30c2014-02-12 17:25:45 -03001330 struct s2255_vc *vc = video_drvdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001331 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001332 int fdec = FDEC_1;
1333 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001334 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1335 return -EINVAL;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001336 mode = vc->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001337 /* high quality capture mode requires a stream restart */
sensoray-dev340a30c2014-02-12 17:25:45 -03001338 if ((vc->cap_parm.capturemode != sp->parm.capture.capturemode)
1339 && vb2_is_streaming(&vc->vb_vidq))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001340 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001341 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1342 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001343 if (def_dem != sp->parm.capture.timeperframe.denominator)
1344 sp->parm.capture.timeperframe.numerator = def_num;
1345 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1346 sp->parm.capture.timeperframe.numerator = def_num;
1347 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1348 sp->parm.capture.timeperframe.numerator = def_num * 2;
1349 fdec = FDEC_2;
1350 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1351 sp->parm.capture.timeperframe.numerator = def_num * 3;
1352 fdec = FDEC_3;
1353 } else {
1354 sp->parm.capture.timeperframe.numerator = def_num * 5;
1355 fdec = FDEC_5;
1356 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001357 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001358 sp->parm.capture.timeperframe.denominator = def_dem;
sensoray-dev340a30c2014-02-12 17:25:45 -03001359 sp->parm.capture.readbuffers = S2255_MIN_BUFS;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001360 s2255_set_mode(vc, &mode);
Dean Anderson92cde472014-02-05 17:38:42 -03001361 dprintk(vc->dev, 4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
Dean Andersone6b44bc2010-03-08 20:04:48 -03001362 __func__,
1363 sp->parm.capture.capturemode,
1364 sp->parm.capture.timeperframe.numerator,
1365 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001366 return 0;
1367}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001368
Hans Verkuil05e5d442013-02-15 06:09:18 -03001369#define NUM_SIZE_ENUMS 3
1370static const struct v4l2_frmsize_discrete ntsc_sizes[] = {
1371 { 640, 480 },
1372 { 640, 240 },
1373 { 320, 240 },
1374};
1375static const struct v4l2_frmsize_discrete pal_sizes[] = {
1376 { 704, 576 },
1377 { 704, 288 },
1378 { 352, 288 },
1379};
1380
1381static int vidioc_enum_framesizes(struct file *file, void *priv,
1382 struct v4l2_frmsizeenum *fe)
1383{
sensoray-dev340a30c2014-02-12 17:25:45 -03001384 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001385 int is_ntsc = vc->std & V4L2_STD_525_60;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001386 const struct s2255_fmt *fmt;
1387
1388 if (fe->index >= NUM_SIZE_ENUMS)
1389 return -EINVAL;
1390
1391 fmt = format_by_fourcc(fe->pixel_format);
1392 if (fmt == NULL)
1393 return -EINVAL;
1394 fe->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1395 fe->discrete = is_ntsc ? ntsc_sizes[fe->index] : pal_sizes[fe->index];
1396 return 0;
1397}
1398
Dean Andersone6b44bc2010-03-08 20:04:48 -03001399static int vidioc_enum_frameintervals(struct file *file, void *priv,
1400 struct v4l2_frmivalenum *fe)
1401{
sensoray-dev340a30c2014-02-12 17:25:45 -03001402 struct s2255_vc *vc = video_drvdata(file);
Hans Verkuil05e5d442013-02-15 06:09:18 -03001403 const struct s2255_fmt *fmt;
1404 const struct v4l2_frmsize_discrete *sizes;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001405 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001406#define NUM_FRAME_ENUMS 4
1407 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
Hans Verkuil05e5d442013-02-15 06:09:18 -03001408 int i;
1409
Mauro Carvalho Chehab199ab8f2012-10-27 16:29:34 -03001410 if (fe->index >= NUM_FRAME_ENUMS)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001411 return -EINVAL;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001412
1413 fmt = format_by_fourcc(fe->pixel_format);
1414 if (fmt == NULL)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001415 return -EINVAL;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001416
1417 sizes = is_ntsc ? ntsc_sizes : pal_sizes;
1418 for (i = 0; i < NUM_SIZE_ENUMS; i++, sizes++)
1419 if (fe->width == sizes->width &&
1420 fe->height == sizes->height)
1421 break;
1422 if (i == NUM_SIZE_ENUMS)
1423 return -EINVAL;
1424
Dean Andersone6b44bc2010-03-08 20:04:48 -03001425 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1426 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1427 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
Dean Anderson92cde472014-02-05 17:38:42 -03001428 dprintk(vc->dev, 4, "%s discrete %d/%d\n", __func__,
sensoray-devf5402002014-01-29 15:24:07 -03001429 fe->discrete.numerator,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001430 fe->discrete.denominator);
1431 return 0;
1432}
1433
sensoray-dev340a30c2014-02-12 17:25:45 -03001434static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001435{
Dean Anderson5e950fa2014-02-04 18:16:24 -03001436 struct s2255_vc *vc = video_drvdata(file);
sensoray-dev340a30c2014-02-12 17:25:45 -03001437 struct s2255_dev *dev = vc->dev;
Dean Anderson14d96262008-08-25 13:58:55 -03001438 int state;
sensoray-dev340a30c2014-02-12 17:25:45 -03001439 int rc = 0;
1440
1441 rc = v4l2_fh_open(file);
1442 if (rc != 0)
1443 return rc;
1444
1445 dprintk(dev, 1, "s2255: %s\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001446 state = atomic_read(&dev->fw_data->fw_state);
1447 switch (state) {
1448 case S2255_FW_DISCONNECTING:
Dean Andersonff7e22d2010-04-08 23:38:07 -03001449 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001450 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001451 s2255_dev_err(&dev->udev->dev,
1452 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001453 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001454 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001455 ((atomic_read(&dev->fw_data->fw_state)
1456 == S2255_FW_SUCCESS) ||
1457 (atomic_read(&dev->fw_data->fw_state)
1458 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001459 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001460 /* state may have changed, re-read */
1461 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001462 break;
1463 case S2255_FW_NOTLOADED:
1464 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001465 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1466 driver loaded and then device immediately opened */
sensoray-devf5402002014-01-29 15:24:07 -03001467 pr_info("%s waiting for firmware load\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001468 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001469 ((atomic_read(&dev->fw_data->fw_state)
1470 == S2255_FW_SUCCESS) ||
1471 (atomic_read(&dev->fw_data->fw_state)
1472 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001473 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001474 /* state may have changed, re-read */
1475 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001476 break;
1477 case S2255_FW_SUCCESS:
1478 default:
1479 break;
1480 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001481 /* state may have changed in above switch statement */
1482 switch (state) {
1483 case S2255_FW_SUCCESS:
1484 break;
1485 case S2255_FW_FAILED:
sensoray-devf5402002014-01-29 15:24:07 -03001486 pr_info("2255 firmware load failed.\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03001487 return -ENODEV;
1488 case S2255_FW_DISCONNECTING:
sensoray-devf5402002014-01-29 15:24:07 -03001489 pr_info("%s: disconnecting\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001490 return -ENODEV;
1491 case S2255_FW_LOADED_DSPWAIT:
1492 case S2255_FW_NOTLOADED:
sensoray-devf5402002014-01-29 15:24:07 -03001493 pr_info("%s: firmware not loaded, please retry\n",
1494 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001495 /*
1496 * Timeout on firmware load means device unusable.
1497 * Set firmware failure state.
1498 * On next s2255_open the firmware will be reloaded.
1499 */
1500 atomic_set(&dev->fw_data->fw_state,
1501 S2255_FW_FAILED);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001502 return -EAGAIN;
1503 default:
sensoray-devf5402002014-01-29 15:24:07 -03001504 pr_info("%s: unknown state\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001505 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001506 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001507 if (!vc->configured) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001508 /* configure channel to default state */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001509 vc->fmt = &formats[0];
1510 s2255_set_mode(vc, &vc->mode);
1511 vc->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001512 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001513 return 0;
1514}
1515
Dean Andersond62e85a2010-04-09 19:54:26 -03001516static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001517{
sensoray-devf5402002014-01-29 15:24:07 -03001518 dprintk(dev, 1, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001519 /* board shutdown stops the read pipe if it is running */
1520 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001521 /* make sure firmware still not trying to load */
Kirill Tkhai9f6be2b2014-04-17 17:47:04 -03001522 del_timer_sync(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001523 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001524 usb_kill_urb(dev->fw_data->fw_urb);
1525 usb_free_urb(dev->fw_data->fw_urb);
1526 dev->fw_data->fw_urb = NULL;
1527 }
Jesper Juhl3fc82fa2012-04-09 16:50:04 -03001528 release_firmware(dev->fw_data->fw);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001529 kfree(dev->fw_data->pfw_data);
1530 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001531 /* reset the DSP so firmware can be reloaded next time */
1532 s2255_reset_dsppower(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001533 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001534 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001535 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03001536 kfree(dev->cmdbuf);
Dean Andersonb7732a32009-03-30 11:59:56 -03001537 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001538}
1539
Hans Verkuilbec43662008-12-30 06:58:20 -03001540static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001541 .owner = THIS_MODULE,
1542 .open = s2255_open,
sensoray-dev340a30c2014-02-12 17:25:45 -03001543 .release = vb2_fop_release,
1544 .poll = vb2_fop_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001545 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
sensoray-dev340a30c2014-02-12 17:25:45 -03001546 .mmap = vb2_fop_mmap,
1547 .read = vb2_fop_read,
Dean Anderson38f993a2008-06-26 23:15:51 -03001548};
1549
Hans Verkuila3998102008-07-21 02:57:38 -03001550static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001551 .vidioc_querycap = vidioc_querycap,
1552 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1553 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1554 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1555 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
sensoray-dev340a30c2014-02-12 17:25:45 -03001556 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1557 .vidioc_querybuf = vb2_ioctl_querybuf,
1558 .vidioc_qbuf = vb2_ioctl_qbuf,
1559 .vidioc_dqbuf = vb2_ioctl_dqbuf,
Dean Anderson38f993a2008-06-26 23:15:51 -03001560 .vidioc_s_std = vidioc_s_std,
Hans Verkuil469af772013-02-15 06:12:58 -03001561 .vidioc_g_std = vidioc_g_std,
Dean Anderson38f993a2008-06-26 23:15:51 -03001562 .vidioc_enum_input = vidioc_enum_input,
1563 .vidioc_g_input = vidioc_g_input,
1564 .vidioc_s_input = vidioc_s_input,
sensoray-dev340a30c2014-02-12 17:25:45 -03001565 .vidioc_streamon = vb2_ioctl_streamon,
1566 .vidioc_streamoff = vb2_ioctl_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001567 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1568 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001569 .vidioc_s_parm = vidioc_s_parm,
1570 .vidioc_g_parm = vidioc_g_parm,
Hans Verkuil05e5d442013-02-15 06:09:18 -03001571 .vidioc_enum_framesizes = vidioc_enum_framesizes,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001572 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuil44d06d82013-02-15 05:59:00 -03001573 .vidioc_log_status = v4l2_ctrl_log_status,
1574 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1575 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001576};
1577
Dean Andersonff7e22d2010-04-08 23:38:07 -03001578static void s2255_video_device_release(struct video_device *vdev)
1579{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001580 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001581 struct s2255_vc *vc =
1582 container_of(vdev, struct s2255_vc, vdev);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001583
sensoray-devf5402002014-01-29 15:24:07 -03001584 dprintk(dev, 4, "%s, chnls: %d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001585 atomic_read(&dev->num_channels));
Hans Verkuil192f1e72013-02-15 05:51:21 -03001586
Dean Anderson5e950fa2014-02-04 18:16:24 -03001587 v4l2_ctrl_handler_free(&vc->hdl);
sensoray-devf5402002014-01-29 15:24:07 -03001588
Dean Andersonfe85ce92010-06-01 19:12:07 -03001589 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001590 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001591 return;
1592}
1593
Hans Verkuila3998102008-07-21 02:57:38 -03001594static struct video_device template = {
1595 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001596 .fops = &s2255_fops_v4l,
1597 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001598 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001599 .tvnorms = S2255_NORMS,
Dean Anderson38f993a2008-06-26 23:15:51 -03001600};
1601
Hans Verkuil192f1e72013-02-15 05:51:21 -03001602static const struct v4l2_ctrl_ops s2255_ctrl_ops = {
1603 .s_ctrl = s2255_s_ctrl,
1604};
1605
1606static const struct v4l2_ctrl_config color_filter_ctrl = {
1607 .ops = &s2255_ctrl_ops,
1608 .name = "Color Filter",
1609 .id = V4L2_CID_S2255_COLORFILTER,
1610 .type = V4L2_CTRL_TYPE_BOOLEAN,
1611 .max = 1,
1612 .step = 1,
1613 .def = 1,
1614};
1615
Dean Anderson38f993a2008-06-26 23:15:51 -03001616static int s2255_probe_v4l(struct s2255_dev *dev)
1617{
1618 int ret;
1619 int i;
1620 int cur_nr = video_nr;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001621 struct s2255_vc *vc;
sensoray-dev340a30c2014-02-12 17:25:45 -03001622 struct vb2_queue *q;
1623
Dean Anderson65c6edb2010-04-20 17:21:32 -03001624 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1625 if (ret)
1626 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001627 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001628 /* register 4 video devices */
1629 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001630 vc = &dev->vc[i];
1631 INIT_LIST_HEAD(&vc->buf_list);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001632
Dean Anderson5e950fa2014-02-04 18:16:24 -03001633 v4l2_ctrl_handler_init(&vc->hdl, 6);
1634 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001635 V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001636 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001637 V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001638 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001639 V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001640 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001641 V4L2_CID_HUE, 0, 255, 1, DEF_HUE);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001642 vc->jpegqual_ctrl = v4l2_ctrl_new_std(&vc->hdl,
Hans Verkuil7041dec2013-02-15 05:53:45 -03001643 &s2255_ctrl_ops,
1644 V4L2_CID_JPEG_COMPRESSION_QUALITY,
1645 0, 100, 1, S2255_DEF_JPEG_QUAL);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001646 if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER &&
Dean Anderson5e950fa2014-02-04 18:16:24 -03001647 (dev->pid != 0x2257 || vc->idx <= 1))
1648 v4l2_ctrl_new_custom(&vc->hdl, &color_filter_ctrl,
sensoray-devf5402002014-01-29 15:24:07 -03001649 NULL);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001650 if (vc->hdl.error) {
1651 ret = vc->hdl.error;
1652 v4l2_ctrl_handler_free(&vc->hdl);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001653 dev_err(&dev->udev->dev, "couldn't register control\n");
1654 break;
1655 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001656 q = &vc->vb_vidq;
1657 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1658 q->io_modes = VB2_MMAP | VB2_READ | VB2_USERPTR;
1659 q->drv_priv = vc;
1660 q->lock = &vc->vb_lock;
1661 q->buf_struct_size = sizeof(struct s2255_buffer);
1662 q->mem_ops = &vb2_vmalloc_memops;
1663 q->ops = &s2255_video_qops;
Sakari Ailusade48682014-02-25 19:12:19 -03001664 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
sensoray-dev340a30c2014-02-12 17:25:45 -03001665 ret = vb2_queue_init(q);
1666 if (ret != 0) {
1667 dev_err(&dev->udev->dev,
1668 "%s vb2_queue_init 0x%x\n", __func__, ret);
1669 break;
1670 }
1671 /* register video devices */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001672 vc->vdev = template;
sensoray-dev340a30c2014-02-12 17:25:45 -03001673 vc->vdev.queue = q;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001674 vc->vdev.ctrl_handler = &vc->hdl;
1675 vc->vdev.lock = &dev->lock;
1676 vc->vdev.v4l2_dev = &dev->v4l2_dev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001677 video_set_drvdata(&vc->vdev, vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03001678 if (video_nr == -1)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001679 ret = video_register_device(&vc->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001680 VFL_TYPE_GRABBER,
1681 video_nr);
1682 else
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 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001686
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001687 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001688 dev_err(&dev->udev->dev,
1689 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001690 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001691 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001692 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001693 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Anderson5e950fa2014-02-04 18:16:24 -03001694 video_device_node_name(&vc->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001695
Dean Anderson38f993a2008-06-26 23:15:51 -03001696 }
sensoray-devf5402002014-01-29 15:24:07 -03001697 pr_info("Sensoray 2255 V4L driver Revision: %s\n",
1698 S2255_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001699 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001700 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001701 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001702 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001703 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001704 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
sensoray-devf5402002014-01-29 15:24:07 -03001705 pr_warn("s2255: Not all channels available.\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001706 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001707}
1708
Dean Anderson38f993a2008-06-26 23:15:51 -03001709/* this function moves the usb stream read pipe data
1710 * into the system buffers.
1711 * returns 0 on success, EAGAIN if more data to process( call this
1712 * function again).
1713 *
1714 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001715 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001716 * bytes 4-7: channel: 0-3
1717 * bytes 8-11: payload size: size of the frame
1718 * bytes 12-payloadsize+12: frame data
1719 */
1720static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1721{
Dean Anderson38f993a2008-06-26 23:15:51 -03001722 char *pdest;
1723 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001724 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001725 char *psrc;
1726 unsigned long copy_size;
1727 unsigned long size;
1728 s32 idx = -1;
1729 struct s2255_framei *frm;
1730 unsigned char *pdata;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001731 struct s2255_vc *vc;
sensoray-devf5402002014-01-29 15:24:07 -03001732 dprintk(dev, 100, "buffer to user\n");
Dean Anderson5e950fa2014-02-04 18:16:24 -03001733 vc = &dev->vc[dev->cc];
1734 idx = vc->cur_frame;
1735 frm = &vc->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001736 if (frm->ulState == S2255_READ_IDLE) {
1737 int jj;
1738 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03001739 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03001740 int payload;
1741 /* search for marker codes */
1742 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03001743 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03001744 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03001745 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03001746 case S2255_MARKER_FRAME:
sensoray-devf5402002014-01-29 15:24:07 -03001747 dprintk(dev, 4, "marker @ offset: %d [%x %x]\n",
1748 jj, pdata[0], pdata[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001749 offset = jj + PREFIX_SIZE;
1750 bframe = 1;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001751 cc = le32_to_cpu(pdword[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001752 if (cc >= MAX_CHANNELS) {
sensoray-devf5402002014-01-29 15:24:07 -03001753 dprintk(dev, 0,
1754 "bad channel\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001755 return -EINVAL;
1756 }
1757 /* reverse it */
1758 dev->cc = G_chnmap[cc];
Dean Anderson5e950fa2014-02-04 18:16:24 -03001759 vc = &dev->vc[dev->cc];
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001760 payload = le32_to_cpu(pdword[3]);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001761 if (payload > vc->req_image_size) {
1762 vc->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03001763 /* discard the bad frame */
1764 return -EINVAL;
1765 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001766 vc->pkt_size = payload;
1767 vc->jpg_size = le32_to_cpu(pdword[4]);
Dean Anderson14d96262008-08-25 13:58:55 -03001768 break;
1769 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001770
Dean Anderson14d96262008-08-25 13:58:55 -03001771 pdata += DEF_USB_BLOCK;
1772 jj += DEF_USB_BLOCK;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001773 if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001774 break;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001775 cc = G_chnmap[le32_to_cpu(pdword[1])];
Roel Kluinf14a2972009-10-23 07:59:42 -03001776 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001777 break;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001778 vc = &dev->vc[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03001779 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03001780 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03001781 /* check if channel valid */
1782 /* set mode ready */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001783 vc->setmode_ready = 1;
1784 wake_up(&vc->wait_setmode);
sensoray-devf5402002014-01-29 15:24:07 -03001785 dprintk(dev, 5, "setmode rdy %d\n", cc);
Dean Anderson14d96262008-08-25 13:58:55 -03001786 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03001787 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03001788 dev->chn_ready |= (1 << cc);
1789 if ((dev->chn_ready & 0x0f) != 0x0f)
1790 break;
1791 /* all channels ready */
sensoray-devf5402002014-01-29 15:24:07 -03001792 pr_info("s2255: fw loaded\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001793 atomic_set(&dev->fw_data->fw_state,
1794 S2255_FW_SUCCESS);
1795 wake_up(&dev->fw_data->wait_fw);
1796 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03001797 case S2255_RESPONSE_STATUS:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001798 vc->vidstatus = le32_to_cpu(pdword[3]);
1799 vc->vidstatus_ready = 1;
1800 wake_up(&vc->wait_vidstatus);
sensoray-devf5402002014-01-29 15:24:07 -03001801 dprintk(dev, 5, "vstat %x chan %d\n",
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001802 le32_to_cpu(pdword[3]), cc);
Dean Anderson4de39f52010-03-03 19:39:19 -03001803 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001804 default:
sensoray-devf5402002014-01-29 15:24:07 -03001805 pr_info("s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001806 }
1807 default:
1808 pdata++;
1809 break;
1810 }
1811 if (bframe)
1812 break;
1813 } /* for */
1814 if (!bframe)
1815 return -EINVAL;
1816 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001817 vc = &dev->vc[dev->cc];
1818 idx = vc->cur_frame;
1819 frm = &vc->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001820 /* search done. now find out if should be acquiring on this channel */
sensoray-dev340a30c2014-02-12 17:25:45 -03001821 if (!vb2_is_streaming(&vc->vb_vidq)) {
Dean Anderson14d96262008-08-25 13:58:55 -03001822 /* we found a frame, but this channel is turned off */
1823 frm->ulState = S2255_READ_IDLE;
1824 return -EINVAL;
1825 }
1826
1827 if (frm->ulState == S2255_READ_IDLE) {
1828 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03001829 frm->cur_size = 0;
1830 }
1831
Dean Anderson14d96262008-08-25 13:58:55 -03001832 /* skip the marker 512 bytes (and offset if out of sync) */
1833 psrc = (u8 *)pipe_info->transfer_buffer + offset;
1834
Dean Anderson38f993a2008-06-26 23:15:51 -03001835
1836 if (frm->lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03001837 dprintk(dev, 1, "s2255 frame buffer == NULL.%p %p %d %d",
Dean Anderson38f993a2008-06-26 23:15:51 -03001838 frm, dev, dev->cc, idx);
1839 return -ENOMEM;
1840 }
1841
1842 pdest = frm->lpvbits + frm->cur_size;
1843
Dean Anderson14d96262008-08-25 13:58:55 -03001844 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03001845
Dean Anderson5e950fa2014-02-04 18:16:24 -03001846 size = vc->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001847
Dean Anderson14d96262008-08-25 13:58:55 -03001848 /* sanity check on pdest */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001849 if ((copy_size + frm->cur_size) < vc->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03001850 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001851
Dean Anderson38f993a2008-06-26 23:15:51 -03001852 frm->cur_size += copy_size;
sensoray-devf5402002014-01-29 15:24:07 -03001853 dprintk(dev, 4, "cur_size: %lu, size: %lu\n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001854
Dean Anderson14d96262008-08-25 13:58:55 -03001855 if (frm->cur_size >= size) {
sensoray-devf5402002014-01-29 15:24:07 -03001856 dprintk(dev, 2, "******[%d]Buffer[%d]full*******\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001857 dev->cc, idx);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001858 vc->last_frame = vc->cur_frame;
1859 vc->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03001860 /* end of system frame ring buffer, start at zero */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001861 if ((vc->cur_frame == SYS_FRAMES) ||
1862 (vc->cur_frame == vc->buffer.dwFrames))
1863 vc->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001864 /* frame ready */
sensoray-dev340a30c2014-02-12 17:25:45 -03001865 if (vb2_is_streaming(&vc->vb_vidq))
Dean Anderson5e950fa2014-02-04 18:16:24 -03001866 s2255_got_frame(vc, vc->jpg_size);
1867 vc->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03001868 frm->ulState = S2255_READ_IDLE;
1869 frm->cur_size = 0;
1870
Dean Anderson38f993a2008-06-26 23:15:51 -03001871 }
1872 /* done successfully */
1873 return 0;
1874}
1875
1876static void s2255_read_video_callback(struct s2255_dev *dev,
1877 struct s2255_pipeinfo *pipe_info)
1878{
1879 int res;
sensoray-devf5402002014-01-29 15:24:07 -03001880 dprintk(dev, 50, "callback read video\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001881
1882 if (dev->cc >= MAX_CHANNELS) {
1883 dev->cc = 0;
1884 dev_err(&dev->udev->dev, "invalid channel\n");
1885 return;
1886 }
1887 /* otherwise copy to the system buffers */
1888 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03001889 if (res != 0)
sensoray-devf5402002014-01-29 15:24:07 -03001890 dprintk(dev, 4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001891
sensoray-devf5402002014-01-29 15:24:07 -03001892 dprintk(dev, 50, "callback read video done\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001893 return;
1894}
1895
1896static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
1897 u16 Index, u16 Value, void *TransferBuffer,
1898 s32 TransferBufferLength, int bOut)
1899{
1900 int r;
1901 if (!bOut) {
1902 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
1903 Request,
1904 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
1905 USB_DIR_IN,
1906 Value, Index, TransferBuffer,
1907 TransferBufferLength, HZ * 5);
1908 } else {
1909 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
1910 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1911 Value, Index, TransferBuffer,
1912 TransferBufferLength, HZ * 5);
1913 }
1914 return r;
1915}
1916
1917/*
1918 * retrieve FX2 firmware version. future use.
1919 * @param dev pointer to device extension
1920 * @return -1 for fail, else returns firmware version as an int(16 bits)
1921 */
1922static int s2255_get_fx2fw(struct s2255_dev *dev)
1923{
1924 int fw;
1925 int ret;
1926 unsigned char transBuffer[64];
1927 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
1928 S2255_VR_IN);
1929 if (ret < 0)
sensoray-devf5402002014-01-29 15:24:07 -03001930 dprintk(dev, 2, "get fw error: %x\n", ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001931 fw = transBuffer[0] + (transBuffer[1] << 8);
sensoray-devf5402002014-01-29 15:24:07 -03001932 dprintk(dev, 2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
Dean Anderson38f993a2008-06-26 23:15:51 -03001933 return fw;
1934}
1935
1936/*
1937 * Create the system ring buffer to copy frames into from the
1938 * usb read pipe.
1939 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001940static int s2255_create_sys_buffers(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03001941{
1942 unsigned long i;
1943 unsigned long reqsize;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001944 vc->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03001945 /* always allocate maximum size(PAL) for system buffers */
1946 reqsize = SYS_FRAMES_MAXSIZE;
1947
1948 if (reqsize > SYS_FRAMES_MAXSIZE)
1949 reqsize = SYS_FRAMES_MAXSIZE;
1950
1951 for (i = 0; i < SYS_FRAMES; i++) {
1952 /* allocate the frames */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001953 vc->buffer.frame[i].lpvbits = vmalloc(reqsize);
1954 vc->buffer.frame[i].size = reqsize;
1955 if (vc->buffer.frame[i].lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03001956 pr_info("out of memory. using less frames\n");
Dean Anderson5e950fa2014-02-04 18:16:24 -03001957 vc->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03001958 break;
1959 }
1960 }
1961
1962 /* make sure internal states are set */
1963 for (i = 0; i < SYS_FRAMES; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001964 vc->buffer.frame[i].ulState = 0;
1965 vc->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001966 }
1967
Dean Anderson5e950fa2014-02-04 18:16:24 -03001968 vc->cur_frame = 0;
1969 vc->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03001970 return 0;
1971}
1972
Dean Anderson5e950fa2014-02-04 18:16:24 -03001973static int s2255_release_sys_buffers(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03001974{
1975 unsigned long i;
Dean Anderson38f993a2008-06-26 23:15:51 -03001976 for (i = 0; i < SYS_FRAMES; i++) {
Markus Elfring83f56f72014-11-20 09:26:36 -03001977 vfree(vc->buffer.frame[i].lpvbits);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001978 vc->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001979 }
1980 return 0;
1981}
1982
1983static int s2255_board_init(struct s2255_dev *dev)
1984{
Dean Anderson38f993a2008-06-26 23:15:51 -03001985 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
1986 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03001987 int j;
1988 struct s2255_pipeinfo *pipe = &dev->pipe;
sensoray-devf5402002014-01-29 15:24:07 -03001989 dprintk(dev, 4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03001990 memset(pipe, 0, sizeof(*pipe));
1991 pipe->dev = dev;
1992 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
1993 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001994
Dean Andersonab85c6a2010-04-08 23:39:12 -03001995 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
1996 GFP_KERNEL);
1997 if (pipe->transfer_buffer == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03001998 dprintk(dev, 1, "out of memory!\n");
Dean Andersonab85c6a2010-04-08 23:39:12 -03001999 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002000 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002001 /* query the firmware */
2002 fw_ver = s2255_get_fx2fw(dev);
2003
sensoray-devf5402002014-01-29 15:24:07 -03002004 pr_info("s2255: usb firmware version %d.%d\n",
2005 (fw_ver >> 8) & 0xff,
2006 fw_ver & 0xff);
Dean Andersonabce21f2009-04-23 16:04:41 -03002007
2008 if (fw_ver < S2255_CUR_USB_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002009 pr_info("s2255: newer USB firmware available\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002010
2011 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002012 struct s2255_vc *vc = &dev->vc[j];
Dean Anderson5e950fa2014-02-04 18:16:24 -03002013 vc->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002014 if (dev->pid == 0x2257 && j > 1)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002015 vc->mode.color |= (1 << 16);
2016 vc->jpegqual = S2255_DEF_JPEG_QUAL;
2017 vc->width = LINE_SZ_4CIFS_NTSC;
2018 vc->height = NUM_LINES_4CIFS_NTSC * 2;
2019 vc->std = V4L2_STD_NTSC_M;
2020 vc->fmt = &formats[0];
2021 vc->mode.restart = 1;
2022 vc->req_image_size = get_transfer_size(&mode_def);
2023 vc->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002024 /* create the system buffers */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002025 s2255_create_sys_buffers(vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03002026 }
2027 /* start read pipe */
2028 s2255_start_readpipe(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002029 dprintk(dev, 1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002030 return 0;
2031}
2032
2033static int s2255_board_shutdown(struct s2255_dev *dev)
2034{
2035 u32 i;
sensoray-devf5402002014-01-29 15:24:07 -03002036 dprintk(dev, 1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002037
2038 for (i = 0; i < MAX_CHANNELS; i++) {
sensoray-dev340a30c2014-02-12 17:25:45 -03002039 if (vb2_is_streaming(&dev->vc[i].vb_vidq))
Dean Anderson5e950fa2014-02-04 18:16:24 -03002040 s2255_stop_acquire(&dev->vc[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002041 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002042 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002043 for (i = 0; i < MAX_CHANNELS; i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002044 s2255_release_sys_buffers(&dev->vc[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002045 /* release transfer buffer */
2046 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002047 return 0;
2048}
2049
2050static void read_pipe_completion(struct urb *purb)
2051{
2052 struct s2255_pipeinfo *pipe_info;
2053 struct s2255_dev *dev;
2054 int status;
2055 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002056 pipe_info = purb->context;
Dean Anderson38f993a2008-06-26 23:15:51 -03002057 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002058 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002059 return;
2060 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002061 dev = pipe_info->dev;
2062 if (dev == 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 }
2066 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002067 /* if shutting down, do not resubmit, exit immediately */
2068 if (status == -ESHUTDOWN) {
sensoray-devf5402002014-01-29 15:24:07 -03002069 dprintk(dev, 2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002070 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002071 return;
2072 }
2073
2074 if (pipe_info->state == 0) {
sensoray-devf5402002014-01-29 15:24:07 -03002075 dprintk(dev, 2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002076 return;
2077 }
2078
Dean Andersonb02064c2009-04-30 12:29:38 -03002079 if (status == 0)
2080 s2255_read_video_callback(dev, pipe_info);
2081 else {
2082 pipe_info->err_count++;
sensoray-devf5402002014-01-29 15:24:07 -03002083 dprintk(dev, 1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002084 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002085
Dean Anderson38f993a2008-06-26 23:15:51 -03002086 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2087 /* reuse urb */
2088 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2089 pipe,
2090 pipe_info->transfer_buffer,
2091 pipe_info->cur_transfer_size,
2092 read_pipe_completion, pipe_info);
2093
2094 if (pipe_info->state != 0) {
sensoray-devf5402002014-01-29 15:24:07 -03002095 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC))
Dean Anderson38f993a2008-06-26 23:15:51 -03002096 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002097 } else {
sensoray-devf5402002014-01-29 15:24:07 -03002098 dprintk(dev, 2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002099 }
2100 return;
2101}
2102
2103static int s2255_start_readpipe(struct s2255_dev *dev)
2104{
2105 int pipe;
2106 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002107 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002108 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
sensoray-devf5402002014-01-29 15:24:07 -03002109 dprintk(dev, 2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002110 pipe_info->state = 1;
2111 pipe_info->err_count = 0;
2112 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2113 if (!pipe_info->stream_urb) {
2114 dev_err(&dev->udev->dev,
2115 "ReadStream: Unable to alloc URB\n");
2116 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002117 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002118 /* transfer buffer allocated in board_init */
2119 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2120 pipe,
2121 pipe_info->transfer_buffer,
2122 pipe_info->cur_transfer_size,
2123 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002124 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2125 if (retval) {
sensoray-devf5402002014-01-29 15:24:07 -03002126 pr_err("s2255: start read pipe failed\n");
Dean Andersonab85c6a2010-04-08 23:39:12 -03002127 return retval;
2128 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002129 return 0;
2130}
2131
2132/* starts acquisition process */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002133static int s2255_start_acquire(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03002134{
Dean Anderson38f993a2008-06-26 23:15:51 -03002135 int res;
2136 unsigned long chn_rev;
2137 int j;
Dean Anderson5e950fa2014-02-04 18:16:24 -03002138 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03002139 __le32 *buffer = dev->cmdbuf;
Dean Anderson38f993a2008-06-26 23:15:51 -03002140
Dean Anderson47d8c882014-02-05 15:43:51 -03002141 mutex_lock(&dev->cmdlock);
2142 chn_rev = G_chnmap[vc->idx];
Dean Anderson5e950fa2014-02-04 18:16:24 -03002143 vc->last_frame = -1;
2144 vc->bad_payload = 0;
2145 vc->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002146 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002147 vc->buffer.frame[j].ulState = 0;
2148 vc->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002149 }
2150
2151 /* send the start command */
Dean Anderson47d8c882014-02-05 15:43:51 -03002152 buffer[0] = IN_DATA_TOKEN;
2153 buffer[1] = (__le32) cpu_to_le32(chn_rev);
2154 buffer[2] = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002155 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2156 if (res != 0)
2157 dev_err(&dev->udev->dev, "CMD_START error\n");
2158
Dean Anderson5e950fa2014-02-04 18:16:24 -03002159 dprintk(dev, 2, "start acquire exit[%d] %d\n", vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03002160 mutex_unlock(&dev->cmdlock);
Dean Anderson6a5b63b2014-02-05 15:58:20 -03002161 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002162}
2163
Dean Anderson5e950fa2014-02-04 18:16:24 -03002164static int s2255_stop_acquire(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03002165{
Dean Anderson38f993a2008-06-26 23:15:51 -03002166 int res;
2167 unsigned long chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03002168 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03002169 __le32 *buffer = dev->cmdbuf;
2170
2171 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03002172 chn_rev = G_chnmap[vc->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002173 /* send the stop command */
Dean Anderson47d8c882014-02-05 15:43:51 -03002174 buffer[0] = IN_DATA_TOKEN;
2175 buffer[1] = (__le32) cpu_to_le32(chn_rev);
2176 buffer[2] = CMD_STOP;
2177
Dean Anderson38f993a2008-06-26 23:15:51 -03002178 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002179 if (res != 0)
2180 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson47d8c882014-02-05 15:43:51 -03002181
Dean Anderson5e950fa2014-02-04 18:16:24 -03002182 dprintk(dev, 4, "%s: chn %d, res %d\n", __func__, vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03002183 mutex_unlock(&dev->cmdlock);
Dean Anderson14d96262008-08-25 13:58:55 -03002184 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002185}
2186
2187static void s2255_stop_readpipe(struct s2255_dev *dev)
2188{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002189 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002190
Dean Andersonab85c6a2010-04-08 23:39:12 -03002191 pipe->state = 0;
2192 if (pipe->stream_urb) {
2193 /* cancel urb */
2194 usb_kill_urb(pipe->stream_urb);
2195 usb_free_urb(pipe->stream_urb);
2196 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002197 }
sensoray-devf5402002014-01-29 15:24:07 -03002198 dprintk(dev, 4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002199 return;
2200}
2201
Dean Anderson14d96262008-08-25 13:58:55 -03002202static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002203{
Dean Anderson14d96262008-08-25 13:58:55 -03002204 if (reset)
2205 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002206 dev->fw_data->fw_size = dev->fw_data->fw->size;
2207 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2208 memcpy(dev->fw_data->pfw_data,
2209 dev->fw_data->fw->data, CHUNK_SIZE);
2210 dev->fw_data->fw_loaded = CHUNK_SIZE;
2211 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2212 usb_sndbulkpipe(dev->udev, 2),
2213 dev->fw_data->pfw_data,
2214 CHUNK_SIZE, s2255_fwchunk_complete,
2215 dev->fw_data);
2216 mod_timer(&dev->timer, jiffies + HZ);
2217}
2218
2219/* standard usb probe function */
2220static int s2255_probe(struct usb_interface *interface,
2221 const struct usb_device_id *id)
2222{
2223 struct s2255_dev *dev = NULL;
2224 struct usb_host_interface *iface_desc;
2225 struct usb_endpoint_descriptor *endpoint;
2226 int i;
2227 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002228 __le32 *pdata;
2229 int fw_size;
Dean Anderson47d8c882014-02-05 15:43:51 -03002230
Dean Anderson38f993a2008-06-26 23:15:51 -03002231 /* allocate memory for our device state and initialize it to zero */
2232 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2233 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002234 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002235 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002236 }
Dean Anderson47d8c882014-02-05 15:43:51 -03002237
2238 dev->cmdbuf = kzalloc(S2255_CMDBUF_SIZE, GFP_KERNEL);
2239 if (dev->cmdbuf == NULL) {
2240 s2255_dev_err(&interface->dev, "out of memory\n");
Daeseok Youne21c94e2014-05-08 19:57:18 -03002241 goto errorFWDATA1;
Dean Anderson47d8c882014-02-05 15:43:51 -03002242 }
2243
Dean Andersonfe85ce92010-06-01 19:12:07 -03002244 atomic_set(&dev->num_channels, 0);
Hans Verkuilff3ec572014-08-20 19:25:34 -03002245 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002246 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2247 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002248 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002249 mutex_init(&dev->lock);
Dean Anderson47d8c882014-02-05 15:43:51 -03002250 mutex_init(&dev->cmdlock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002251 /* grab usb_device and save it */
2252 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2253 if (dev->udev == NULL) {
2254 dev_err(&interface->dev, "null usb device\n");
2255 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002256 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002257 }
sensoray-devf5402002014-01-29 15:24:07 -03002258 dev_dbg(&interface->dev, "dev: %p, udev %p interface %p\n",
2259 dev, dev->udev, interface);
Dean Anderson38f993a2008-06-26 23:15:51 -03002260 dev->interface = interface;
2261 /* set up the endpoint information */
2262 iface_desc = interface->cur_altsetting;
sensoray-devf5402002014-01-29 15:24:07 -03002263 dev_dbg(&interface->dev, "num EP: %d\n",
2264 iface_desc->desc.bNumEndpoints);
Dean Anderson38f993a2008-06-26 23:15:51 -03002265 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2266 endpoint = &iface_desc->endpoint[i].desc;
2267 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2268 /* we found the bulk in endpoint */
2269 dev->read_endpoint = endpoint->bEndpointAddress;
2270 }
2271 }
2272
2273 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002274 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002275 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002276 }
Julia Lawall8bf554c2014-12-26 11:35:33 -03002277 setup_timer(&dev->timer, s2255_timer, (unsigned long)dev->fw_data);
Dean Anderson38f993a2008-06-26 23:15:51 -03002278 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002279 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002280 struct s2255_vc *vc = &dev->vc[i];
2281 vc->idx = i;
2282 vc->dev = dev;
2283 init_waitqueue_head(&vc->wait_setmode);
2284 init_waitqueue_head(&vc->wait_vidstatus);
sensoray-dev340a30c2014-02-12 17:25:45 -03002285 spin_lock_init(&vc->qlock);
2286 mutex_init(&vc->vb_lock);
Dean Anderson4de39f52010-03-03 19:39:19 -03002287 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002288
2289 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002290 if (!dev->fw_data->fw_urb) {
2291 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002292 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002293 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002294
Dean Anderson38f993a2008-06-26 23:15:51 -03002295 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2296 if (!dev->fw_data->pfw_data) {
2297 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002298 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002299 }
2300 /* load the first chunk */
2301 if (request_firmware(&dev->fw_data->fw,
2302 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
sensoray-devf5402002014-01-29 15:24:07 -03002303 dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002304 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002305 }
Dean Anderson14d96262008-08-25 13:58:55 -03002306 /* check the firmware is valid */
2307 fw_size = dev->fw_data->fw->size;
2308 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002309
Dean Anderson14d96262008-08-25 13:58:55 -03002310 if (*pdata != S2255_FW_MARKER) {
sensoray-devf5402002014-01-29 15:24:07 -03002311 dev_err(&interface->dev, "Firmware invalid.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002312 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002313 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002314 } else {
2315 /* make sure firmware is the latest */
2316 __le32 *pRel;
2317 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
sensoray-devf5402002014-01-29 15:24:07 -03002318 pr_info("s2255 dsp fw version %x\n", le32_to_cpu(*pRel));
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002319 dev->dsp_fw_ver = le32_to_cpu(*pRel);
2320 if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002321 pr_info("s2255: f2255usb.bin out of date.\n");
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002322 if (dev->pid == 0x2257 &&
2323 dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
sensoray-devf5402002014-01-29 15:24:07 -03002324 pr_warn("2257 needs firmware %d or above.\n",
2325 S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002326 }
Dean Anderson14d96262008-08-25 13:58:55 -03002327 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002328 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002329 retval = s2255_board_init(dev);
2330 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002331 goto errorBOARDINIT;
Dean Anderson14d96262008-08-25 13:58:55 -03002332 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002333 /* loads v4l specific */
2334 retval = s2255_probe_v4l(dev);
2335 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002336 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002337 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2338 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002339errorBOARDINIT:
2340 s2255_board_shutdown(dev);
2341errorFWMARKER:
2342 release_firmware(dev->fw_data->fw);
2343errorREQFW:
2344 kfree(dev->fw_data->pfw_data);
2345errorFWDATA2:
2346 usb_free_urb(dev->fw_data->fw_urb);
2347errorFWURB:
Kirill Tkhai9f6be2b2014-04-17 17:47:04 -03002348 del_timer_sync(&dev->timer);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002349errorEP:
2350 usb_put_dev(dev->udev);
2351errorUDEV:
2352 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002353 mutex_destroy(&dev->lock);
2354errorFWDATA1:
Dean Anderson47d8c882014-02-05 15:43:51 -03002355 kfree(dev->cmdbuf);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002356 kfree(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002357 pr_warn("Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002358 return retval;
2359}
2360
2361/* disconnect routine. when board is removed physically or with rmmod */
2362static void s2255_disconnect(struct usb_interface *interface)
2363{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002364 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002365 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002366 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002367 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002368 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002369 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002370 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002371 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002372 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002373 for (i = 0; i < channels; i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002374 video_unregister_device(&dev->vc[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002375 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002376 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2377 wake_up(&dev->fw_data->wait_fw);
2378 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002379 dev->vc[i].setmode_ready = 1;
2380 wake_up(&dev->vc[i].wait_setmode);
2381 dev->vc[i].vidstatus_ready = 1;
2382 wake_up(&dev->vc[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002383 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002384 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002385 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002386 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002387}
2388
2389static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002390 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002391 .probe = s2255_probe,
2392 .disconnect = s2255_disconnect,
2393 .id_table = s2255_table,
2394};
2395
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002396module_usb_driver(s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002397
2398MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2399MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2400MODULE_LICENSE("GPL");
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03002401MODULE_VERSION(S2255_VERSION);
Tim Gardner1bec9822012-07-24 16:52:27 -03002402MODULE_FIRMWARE(FIRMWARE_FILE_NAME);