blob: 5f09a5690145063fc3cf2b1769de84c7e373ad38 [file] [log] [blame]
Dean Anderson38f993a2008-06-26 23:15:51 -03001/*
2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
3 *
Dean Andersond86c6a82014-02-04 17:18:03 -03004 * Copyright (C) 2007-2014 by Sensoray Company Inc.
Dean Anderson38f993a2008-06-26 23:15:51 -03005 * Dean Anderson
6 *
7 * Some video buffer code based on vivi driver:
8 *
9 * Sensoray 2255 device supports 4 simultaneous channels.
10 * The channels are not "crossbar" inputs, they are physically
11 * attached to separate video decoders.
12 *
13 * Because of USB2.0 bandwidth limitations. There is only a
14 * certain amount of data which may be transferred at one time.
15 *
16 * Example maximum bandwidth utilization:
17 *
18 * -full size, color mode YUYV or YUV422P: 2 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030019 * -full or half size Grey scale: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030020 * -half size, color mode YUYV or YUV422P: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030021 * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
22 * at once.
Dean Anderson38f993a2008-06-26 23:15:51 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * (at your option) any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 */
38
39#include <linux/module.h>
40#include <linux/firmware.h>
41#include <linux/kernel.h>
42#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090043#include <linux/slab.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030044#include <linux/videodev2.h>
Hans Verkuilfeb75f02008-07-27 06:30:21 -030045#include <linux/mm.h>
Hans Verkuil44d06d82013-02-15 05:59:00 -030046#include <linux/vmalloc.h>
47#include <linux/usb.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030048#include <media/videobuf-vmalloc.h>
49#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030050#include <media/v4l2-device.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030051#include <media/v4l2-ioctl.h>
Hans Verkuil192f1e72013-02-15 05:51:21 -030052#include <media/v4l2-ctrls.h>
Hans Verkuil44d06d82013-02-15 05:59:00 -030053#include <media/v4l2-event.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030054
Dean Andersond86c6a82014-02-04 17:18:03 -030055#define S2255_VERSION "1.24.1"
Dean Anderson38f993a2008-06-26 23:15:51 -030056#define FIRMWARE_FILE_NAME "f2255usb.bin"
57
Dean Anderson22b88d42008-08-29 15:33:19 -030058/* default JPEG quality */
59#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030060/* vendor request in */
61#define S2255_VR_IN 0
62/* vendor request out */
63#define S2255_VR_OUT 1
64/* firmware query */
65#define S2255_VR_FW 0x30
66/* USB endpoint number for configuring the device */
67#define S2255_CONFIG_EP 2
68/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030069#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030070/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030071#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson38f993a2008-06-26 23:15:51 -030072#define S2255_DEF_BUFS 16
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
215struct s2255_channel {
sensoray-devf5402002014-01-29 15:24:07 -0300216 struct s2255_dev *dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300217 struct video_device vdev;
Hans Verkuil192f1e72013-02-15 05:51:21 -0300218 struct v4l2_ctrl_handler hdl;
Hans Verkuil7041dec2013-02-15 05:53:45 -0300219 struct v4l2_ctrl *jpegqual_ctrl;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300220 int resources;
Dean Andersond86c6a82014-02-04 17:18:03 -0300221 struct list_head buf_list;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300222 struct s2255_bufferi buffer;
223 struct s2255_mode mode;
Hans Verkuil469af772013-02-15 06:12:58 -0300224 v4l2_std_id std;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300225 /* jpeg compression */
Hans Verkuil7041dec2013-02-15 05:53:45 -0300226 unsigned jpegqual;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300227 /* capture parameters (for high quality mode full size) */
228 struct v4l2_captureparm cap_parm;
229 int cur_frame;
230 int last_frame;
231
232 int b_acquire;
233 /* allocated image size */
234 unsigned long req_image_size;
235 /* received packet size */
236 unsigned long pkt_size;
237 int bad_payload;
238 unsigned long frame_count;
239 /* if JPEG image */
240 int jpg_size;
241 /* if channel configured to default state */
242 int configured;
243 wait_queue_head_t wait_setmode;
244 int setmode_ready;
245 /* video status items */
246 int vidstatus;
247 wait_queue_head_t wait_vidstatus;
248 int vidstatus_ready;
249 unsigned int width;
250 unsigned int height;
251 const struct s2255_fmt *fmt;
252 int idx; /* channel number on device, 0-3 */
253};
254
Dean Anderson38f993a2008-06-26 23:15:51 -0300255
256struct s2255_dev {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300257 struct s2255_channel channel[MAX_CHANNELS];
sensoray-devf5402002014-01-29 15:24:07 -0300258 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300259 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300260 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300261 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson38f993a2008-06-26 23:15:51 -0300262 struct usb_device *udev;
263 struct usb_interface *interface;
264 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300265 struct timer_list timer;
266 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300267 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300268 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300269 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300270 int chn_ready;
Dean Anderson38f993a2008-06-26 23:15:51 -0300271 spinlock_t slock;
Dean Anderson4de39f52010-03-03 19:39:19 -0300272 /* dsp firmware version (f2255usb.bin) */
273 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300274 u16 pid; /* product id */
Dean Anderson38f993a2008-06-26 23:15:51 -0300275};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300276
Dean Anderson65c6edb2010-04-20 17:21:32 -0300277static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
278{
279 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
280}
Dean Anderson38f993a2008-06-26 23:15:51 -0300281
282struct s2255_fmt {
283 char *name;
284 u32 fourcc;
285 int depth;
286};
287
288/* buffer for one video frame */
289struct s2255_buffer {
290 /* common v4l buffer stuff -- must be first */
291 struct videobuf_buffer vb;
292 const struct s2255_fmt *fmt;
293};
294
295struct s2255_fh {
Hans Verkuil44d06d82013-02-15 05:59:00 -0300296 /* this must be the first field in this struct */
297 struct v4l2_fh fh;
Dean Anderson38f993a2008-06-26 23:15:51 -0300298 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300299 struct videobuf_queue vb_vidq;
300 enum v4l2_buf_type type;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300301 struct s2255_channel *channel;
302 int resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300303};
304
Dean Andersonabce21f2009-04-23 16:04:41 -0300305/* current cypress EEPROM firmware version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300306#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
Dean Anderson4de39f52010-03-03 19:39:19 -0300307/* current DSP FW version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300308#define S2255_CUR_DSP_FWVER 10104
Dean Anderson4de39f52010-03-03 19:39:19 -0300309/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300310#define S2255_MIN_DSP_STATUS 5
311#define S2255_MIN_DSP_COLORFILTER 8
Hans Verkuil469af772013-02-15 06:12:58 -0300312#define S2255_NORMS (V4L2_STD_ALL)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300313
314/* private V4L2 controls */
315
316/*
317 * The following chart displays how COLORFILTER should be set
318 * =========================================================
319 * = fourcc = COLORFILTER =
320 * = ===============================
321 * = = 0 = 1 =
322 * =========================================================
323 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
324 * = = s-video or = composite =
325 * = = B/W camera = input =
326 * =========================================================
327 * = other = color, svideo = color, =
328 * = = = composite =
329 * =========================================================
330 *
331 * Notes:
332 * channels 0-3 on 2255 are composite
333 * channels 0-1 on 2257 are composite, 2-3 are s-video
334 * If COLORFILTER is 0 with a composite color camera connected,
335 * the output will appear monochrome but hatching
336 * will occur.
337 * COLORFILTER is different from "color killer" and "color effects"
338 * for reasons above.
339 */
340#define S2255_V4L2_YC_ON 1
341#define S2255_V4L2_YC_OFF 0
Hans Verkuil192f1e72013-02-15 05:51:21 -0300342#define V4L2_CID_S2255_COLORFILTER (V4L2_CID_USER_S2255_BASE + 0)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300343
Dean Anderson38f993a2008-06-26 23:15:51 -0300344/* frame prefix size (sent once every frame) */
345#define PREFIX_SIZE 512
346
347/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300348static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300349
Dean Anderson38f993a2008-06-26 23:15:51 -0300350static int debug;
Dean Anderson38f993a2008-06-26 23:15:51 -0300351
352static int s2255_start_readpipe(struct s2255_dev *dev);
353static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300354static int s2255_start_acquire(struct s2255_channel *channel);
355static int s2255_stop_acquire(struct s2255_channel *channel);
356static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
357 int jpgsize);
358static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300359static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300360static void s2255_fwload_start(struct s2255_dev *dev, int reset);
Dean Andersond62e85a2010-04-09 19:54:26 -0300361static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300362static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
363 u16 index, u16 value, void *buf,
364 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300365
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300366/* dev_err macro with driver name */
367#define S2255_DRIVER_NAME "s2255"
368#define s2255_dev_err(dev, fmt, arg...) \
369 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
370
sensoray-devf5402002014-01-29 15:24:07 -0300371#define dprintk(dev, level, fmt, arg...) \
372 v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
Dean Anderson38f993a2008-06-26 23:15:51 -0300373
Dean Anderson38f993a2008-06-26 23:15:51 -0300374static struct usb_driver s2255_driver;
375
Dean Anderson38f993a2008-06-26 23:15:51 -0300376/* Declare static vars that will be used as parameters */
377static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
378
379/* start video number */
380static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
381
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300382/* Enable jpeg capture. */
383static int jpeg_enable = 1;
384
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300385module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300386MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300387module_param(vid_limit, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300388MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300389module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300390MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300391module_param(jpeg_enable, int, 0644);
392MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
Dean Anderson38f993a2008-06-26 23:15:51 -0300393
394/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300395#define USB_SENSORAY_VID 0x1943
Dean Anderson38f993a2008-06-26 23:15:51 -0300396static struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300397 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
398 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300399 { } /* Terminating entry */
400};
401MODULE_DEVICE_TABLE(usb, s2255_table);
402
Dean Anderson38f993a2008-06-26 23:15:51 -0300403#define BUFFER_TIMEOUT msecs_to_jiffies(400)
404
Dean Anderson38f993a2008-06-26 23:15:51 -0300405/* image formats. */
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300406/* JPEG formats must be defined last to support jpeg_enable parameter */
Dean Anderson38f993a2008-06-26 23:15:51 -0300407static const struct s2255_fmt formats[] = {
408 {
Dean Anderson38f993a2008-06-26 23:15:51 -0300409 .name = "4:2:2, packed, YUYV",
410 .fourcc = V4L2_PIX_FMT_YUYV,
411 .depth = 16
412
413 }, {
414 .name = "4:2:2, packed, UYVY",
415 .fourcc = V4L2_PIX_FMT_UYVY,
416 .depth = 16
417 }, {
Hans Verkuil5c632b22013-02-26 14:29:04 -0300418 .name = "4:2:2, planar, YUV422P",
419 .fourcc = V4L2_PIX_FMT_YUV422P,
420 .depth = 16
421
422 }, {
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300423 .name = "8bpp GREY",
424 .fourcc = V4L2_PIX_FMT_GREY,
425 .depth = 8
426 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300427 .name = "JPG",
428 .fourcc = V4L2_PIX_FMT_JPEG,
429 .depth = 24
430 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300431 .name = "MJPG",
432 .fourcc = V4L2_PIX_FMT_MJPEG,
433 .depth = 24
Dean Anderson38f993a2008-06-26 23:15:51 -0300434 }
435};
436
Hans Verkuil469af772013-02-15 06:12:58 -0300437static int norm_maxw(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -0300438{
Hans Verkuil469af772013-02-15 06:12:58 -0300439 return (channel->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300440 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
441}
442
Hans Verkuil469af772013-02-15 06:12:58 -0300443static int norm_maxh(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -0300444{
Hans Verkuil469af772013-02-15 06:12:58 -0300445 return (channel->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300446 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
447}
448
Hans Verkuil469af772013-02-15 06:12:58 -0300449static int norm_minw(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -0300450{
Hans Verkuil469af772013-02-15 06:12:58 -0300451 return (channel->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300452 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
453}
454
Hans Verkuil469af772013-02-15 06:12:58 -0300455static int norm_minh(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -0300456{
Hans Verkuil469af772013-02-15 06:12:58 -0300457 return (channel->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300458 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
459}
460
461
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300462/*
463 * TODO: fixme: move YUV reordering to hardware
464 * converts 2255 planar format to yuyv or uyvy
465 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300466static void planar422p_to_yuv_packed(const unsigned char *in,
467 unsigned char *out,
468 int width, int height,
469 int fmt)
470{
471 unsigned char *pY;
472 unsigned char *pCb;
473 unsigned char *pCr;
474 unsigned long size = height * width;
475 unsigned int i;
476 pY = (unsigned char *)in;
477 pCr = (unsigned char *)in + height * width;
478 pCb = (unsigned char *)in + height * width + (height * width / 2);
479 for (i = 0; i < size * 2; i += 4) {
480 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
481 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
482 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
483 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
484 }
485 return;
486}
487
Hans Verkuild45b9b82008-09-04 03:33:43 -0300488static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300489{
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300490 s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
sensoray-devf5402002014-01-29 15:24:07 -0300491 msleep(20);
Dean Anderson14d96262008-08-25 13:58:55 -0300492 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300493 msleep(600);
494 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300495 return;
496}
Dean Anderson38f993a2008-06-26 23:15:51 -0300497
498/* kickstarts the firmware loading. from probe
499 */
500static void s2255_timer(unsigned long user_data)
501{
502 struct s2255_fw *data = (struct s2255_fw *)user_data;
Dean Anderson38f993a2008-06-26 23:15:51 -0300503 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
sensoray-devf5402002014-01-29 15:24:07 -0300504 pr_err("s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300505 atomic_set(&data->fw_state, S2255_FW_FAILED);
506 /* wake up anything waiting for the firmware */
507 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300508 return;
509 }
510}
511
Dean Anderson38f993a2008-06-26 23:15:51 -0300512
513/* this loads the firmware asynchronously.
Hans Verkuil0b84caa2013-02-26 14:14:19 -0300514 Originally this was done synchronously in probe.
Dean Anderson38f993a2008-06-26 23:15:51 -0300515 But it is better to load it asynchronously here than block
516 inside the probe function. Blocking inside probe affects boot time.
517 FW loading is triggered by the timer in the probe function
518*/
519static void s2255_fwchunk_complete(struct urb *urb)
520{
521 struct s2255_fw *data = urb->context;
522 struct usb_device *udev = urb->dev;
523 int len;
Dean Anderson38f993a2008-06-26 23:15:51 -0300524 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300525 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300526 atomic_set(&data->fw_state, S2255_FW_FAILED);
527 /* wake up anything waiting for the firmware */
528 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300529 return;
530 }
531 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300532 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300533 atomic_set(&data->fw_state, S2255_FW_FAILED);
534 /* wake up anything waiting for the firmware */
535 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300536 return;
537 }
538#define CHUNK_SIZE 512
539 /* all USB transfers must be done with continuous kernel memory.
540 can't allocate more than 128k in current linux kernel, so
541 upload the firmware in chunks
542 */
543 if (data->fw_loaded < data->fw_size) {
544 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
545 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
546
547 if (len < CHUNK_SIZE)
548 memset(data->pfw_data, 0, CHUNK_SIZE);
549
Dean Anderson38f993a2008-06-26 23:15:51 -0300550 memcpy(data->pfw_data,
551 (char *) data->fw->data + data->fw_loaded, len);
552
553 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
554 data->pfw_data, CHUNK_SIZE,
555 s2255_fwchunk_complete, data);
556 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
557 dev_err(&udev->dev, "failed submit URB\n");
558 atomic_set(&data->fw_state, S2255_FW_FAILED);
559 /* wake up anything waiting for the firmware */
560 wake_up(&data->wait_fw);
561 return;
562 }
563 data->fw_loaded += len;
sensoray-devf5402002014-01-29 15:24:07 -0300564 } else
Dean Anderson38f993a2008-06-26 23:15:51 -0300565 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson38f993a2008-06-26 23:15:51 -0300566 return;
567
568}
569
Dean Andersonfe85ce92010-06-01 19:12:07 -0300570static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300571{
Dean Anderson38f993a2008-06-26 23:15:51 -0300572 struct s2255_buffer *buf;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300573 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300574 unsigned long flags = 0;
575 int rc = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300576 spin_lock_irqsave(&dev->slock, flags);
Dean Andersond86c6a82014-02-04 17:18:03 -0300577 if (list_empty(&channel->buf_list)) {
sensoray-devf5402002014-01-29 15:24:07 -0300578 dprintk(dev, 1, "No active queue to serve\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300579 rc = -1;
580 goto unlock;
581 }
Dean Andersond86c6a82014-02-04 17:18:03 -0300582 buf = list_entry(channel->buf_list.next,
Dean Anderson38f993a2008-06-26 23:15:51 -0300583 struct s2255_buffer, vb.queue);
Dean Anderson38f993a2008-06-26 23:15:51 -0300584 list_del(&buf->vb.queue);
Sakari Ailus8e6057b2012-09-15 15:14:42 -0300585 v4l2_get_timestamp(&buf->vb.ts);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300586 s2255_fillbuff(channel, buf, jpgsize);
Dean Anderson38f993a2008-06-26 23:15:51 -0300587 wake_up(&buf->vb.done);
sensoray-devf5402002014-01-29 15:24:07 -0300588 dprintk(dev, 2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
Dean Anderson38f993a2008-06-26 23:15:51 -0300589unlock:
590 spin_unlock_irqrestore(&dev->slock, flags);
Julia Lawallf2770972010-08-16 13:26:13 -0300591 return rc;
Dean Anderson38f993a2008-06-26 23:15:51 -0300592}
593
Dean Anderson38f993a2008-06-26 23:15:51 -0300594static const struct s2255_fmt *format_by_fourcc(int fourcc)
595{
596 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300597 for (i = 0; i < ARRAY_SIZE(formats); i++) {
598 if (-1 == formats[i].fourcc)
599 continue;
sensoray-devf5402002014-01-29 15:24:07 -0300600 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
601 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
602 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300603 if (formats[i].fourcc == fourcc)
604 return formats + i;
605 }
606 return NULL;
607}
608
Dean Anderson38f993a2008-06-26 23:15:51 -0300609/* video buffer vmalloc implementation based partly on VIVI driver which is
610 * Copyright (c) 2006 by
611 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
612 * Ted Walther <ted--a.t--enumera.com>
613 * John Sokol <sokol--a.t--videotechnology.com>
614 * http://v4l.videotechnology.com/
615 *
616 */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300617static void s2255_fillbuff(struct s2255_channel *channel,
618 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300619{
620 int pos = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300621 const char *tmpbuf;
622 char *vbuf = videobuf_to_vmalloc(&buf->vb);
623 unsigned long last_frame;
sensoray-devf5402002014-01-29 15:24:07 -0300624 struct s2255_dev *dev = channel->dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300625
626 if (!vbuf)
627 return;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300628 last_frame = channel->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300629 if (last_frame != -1) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300630 tmpbuf =
Dean Andersonfe85ce92010-06-01 19:12:07 -0300631 (const char *)channel->buffer.frame[last_frame].lpvbits;
Dean Anderson38f993a2008-06-26 23:15:51 -0300632 switch (buf->fmt->fourcc) {
633 case V4L2_PIX_FMT_YUYV:
634 case V4L2_PIX_FMT_UYVY:
635 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
636 vbuf, buf->vb.width,
637 buf->vb.height,
638 buf->fmt->fourcc);
639 break;
640 case V4L2_PIX_FMT_GREY:
641 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
642 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300643 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300644 case V4L2_PIX_FMT_MJPEG:
Dean Anderson14d96262008-08-25 13:58:55 -0300645 buf->vb.size = jpgsize;
646 memcpy(vbuf, tmpbuf, buf->vb.size);
647 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300648 case V4L2_PIX_FMT_YUV422P:
649 memcpy(vbuf, tmpbuf,
650 buf->vb.width * buf->vb.height * 2);
651 break;
652 default:
sensoray-devf5402002014-01-29 15:24:07 -0300653 pr_info("s2255: unknown format?\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300654 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300655 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300656 } else {
sensoray-devf5402002014-01-29 15:24:07 -0300657 pr_err("s2255: =======no frame\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300658 return;
Dean Anderson38f993a2008-06-26 23:15:51 -0300659 }
sensoray-devf5402002014-01-29 15:24:07 -0300660 dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n",
Dean Anderson38f993a2008-06-26 23:15:51 -0300661 (unsigned long)vbuf, pos);
662 /* tell v4l buffer was filled */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300663 buf->vb.field_count = channel->frame_count * 2;
Sakari Ailus8e6057b2012-09-15 15:14:42 -0300664 v4l2_get_timestamp(&buf->vb.ts);
Dean Anderson38f993a2008-06-26 23:15:51 -0300665 buf->vb.state = VIDEOBUF_DONE;
666}
667
668
669/* ------------------------------------------------------------------
670 Videobuf operations
671 ------------------------------------------------------------------*/
672
673static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
674 unsigned int *size)
675{
676 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300677 struct s2255_channel *channel = fh->channel;
678 *size = channel->width * channel->height * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300679
680 if (0 == *count)
681 *count = S2255_DEF_BUFS;
682
Andreas Bombedab7e312010-03-21 16:02:45 -0300683 if (*size * *count > vid_limit * 1024 * 1024)
684 *count = (vid_limit * 1024 * 1024) / *size;
Dean Anderson38f993a2008-06-26 23:15:51 -0300685
686 return 0;
687}
688
689static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
690{
Dean Anderson38f993a2008-06-26 23:15:51 -0300691 videobuf_vmalloc_free(&buf->vb);
692 buf->vb.state = VIDEOBUF_NEEDS_INIT;
693}
694
695static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
696 enum v4l2_field field)
697{
698 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300699 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300700 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
701 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300702 int w = channel->width;
703 int h = channel->height;
sensoray-devf5402002014-01-29 15:24:07 -0300704 dprintk(fh->dev, 4, "%s, field=%d\n", __func__, field);
Dean Andersonfe85ce92010-06-01 19:12:07 -0300705 if (channel->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300706 return -EINVAL;
707
Hans Verkuil469af772013-02-15 06:12:58 -0300708 if ((w < norm_minw(channel)) ||
709 (w > norm_maxw(channel)) ||
710 (h < norm_minh(channel)) ||
711 (h > norm_maxh(channel))) {
sensoray-devf5402002014-01-29 15:24:07 -0300712 dprintk(fh->dev, 4, "invalid buffer prepare\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300713 return -EINVAL;
714 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300715 buf->vb.size = w * h * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300716 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
sensoray-devf5402002014-01-29 15:24:07 -0300717 dprintk(fh->dev, 4, "invalid buffer prepare\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300718 return -EINVAL;
719 }
720
Dean Andersonfe85ce92010-06-01 19:12:07 -0300721 buf->fmt = channel->fmt;
722 buf->vb.width = w;
723 buf->vb.height = h;
Dean Anderson38f993a2008-06-26 23:15:51 -0300724 buf->vb.field = field;
725
Dean Anderson38f993a2008-06-26 23:15:51 -0300726 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
727 rc = videobuf_iolock(vq, &buf->vb, NULL);
728 if (rc < 0)
729 goto fail;
730 }
731
732 buf->vb.state = VIDEOBUF_PREPARED;
733 return 0;
734fail:
735 free_buffer(vq, buf);
736 return rc;
737}
738
739static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
740{
741 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
742 struct s2255_fh *fh = vq->priv_data;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300743 struct s2255_channel *channel = fh->channel;
sensoray-devf5402002014-01-29 15:24:07 -0300744 dprintk(fh->dev, 1, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300745 buf->vb.state = VIDEOBUF_QUEUED;
Dean Andersond86c6a82014-02-04 17:18:03 -0300746 list_add_tail(&buf->vb.queue, &channel->buf_list);
Dean Anderson38f993a2008-06-26 23:15:51 -0300747}
748
749static void buffer_release(struct videobuf_queue *vq,
750 struct videobuf_buffer *vb)
751{
752 struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
753 struct s2255_fh *fh = vq->priv_data;
sensoray-devf5402002014-01-29 15:24:07 -0300754 dprintk(fh->dev, 4, "%s %d\n", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -0300755 free_buffer(vq, buf);
756}
757
758static struct videobuf_queue_ops s2255_video_qops = {
759 .buf_setup = buffer_setup,
760 .buf_prepare = buffer_prepare,
761 .buf_queue = buffer_queue,
762 .buf_release = buffer_release,
763};
764
765
Dean Andersonfe85ce92010-06-01 19:12:07 -0300766static int res_get(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300767{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300768 struct s2255_channel *channel = fh->channel;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300769 /* is it free? */
770 if (channel->resources)
771 return 0; /* no, someone else uses it */
Dean Anderson38f993a2008-06-26 23:15:51 -0300772 /* it's free, grab it */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300773 channel->resources = 1;
774 fh->resources = 1;
sensoray-devf5402002014-01-29 15:24:07 -0300775 dprintk(fh->dev, 1, "s2255: res: get\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300776 return 1;
777}
778
Dean Andersonfe85ce92010-06-01 19:12:07 -0300779static int res_locked(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300780{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300781 return fh->channel->resources;
Dean Anderson38f993a2008-06-26 23:15:51 -0300782}
783
Dean Andersonf78d92c2008-07-22 14:43:27 -0300784static int res_check(struct s2255_fh *fh)
785{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300786 return fh->resources;
Dean Andersonf78d92c2008-07-22 14:43:27 -0300787}
788
789
Dean Andersonfe85ce92010-06-01 19:12:07 -0300790static void res_free(struct s2255_fh *fh)
Dean Anderson38f993a2008-06-26 23:15:51 -0300791{
Dean Andersonfe85ce92010-06-01 19:12:07 -0300792 struct s2255_channel *channel = fh->channel;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300793 channel->resources = 0;
794 fh->resources = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300795}
796
Dean Anderson38f993a2008-06-26 23:15:51 -0300797static int vidioc_querycap(struct file *file, void *priv,
798 struct v4l2_capability *cap)
799{
800 struct s2255_fh *fh = file->private_data;
801 struct s2255_dev *dev = fh->dev;
Hans Verkuil39696002013-02-07 07:06:21 -0300802
Dean Anderson38f993a2008-06-26 23:15:51 -0300803 strlcpy(cap->driver, "s2255", sizeof(cap->driver));
804 strlcpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300805 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
Hans Verkuil39696002013-02-07 07:06:21 -0300806 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
807 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300808 return 0;
809}
810
811static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
812 struct v4l2_fmtdesc *f)
813{
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300814 int index = f->index;
Dean Anderson38f993a2008-06-26 23:15:51 -0300815
816 if (index >= ARRAY_SIZE(formats))
817 return -EINVAL;
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300818 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
819 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
820 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300821 strlcpy(f->description, formats[index].name, sizeof(f->description));
822 f->pixelformat = formats[index].fourcc;
823 return 0;
824}
825
826static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
827 struct v4l2_format *f)
828{
829 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300830 struct s2255_channel *channel = fh->channel;
Hans Verkuil92513612013-02-15 06:05:08 -0300831 int is_ntsc = channel->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300832
Dean Andersonfe85ce92010-06-01 19:12:07 -0300833 f->fmt.pix.width = channel->width;
834 f->fmt.pix.height = channel->height;
Hans Verkuil92513612013-02-15 06:05:08 -0300835 if (f->fmt.pix.height >=
836 (is_ntsc ? NUM_LINES_1CIFS_NTSC : NUM_LINES_1CIFS_PAL) * 2)
837 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
838 else
839 f->fmt.pix.field = V4L2_FIELD_TOP;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300840 f->fmt.pix.pixelformat = channel->fmt->fourcc;
841 f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300842 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300843 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
844 f->fmt.pix.priv = 0;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300845 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300846}
847
848static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
849 struct v4l2_format *f)
850{
851 const struct s2255_fmt *fmt;
852 enum v4l2_field field;
Dean Anderson38f993a2008-06-26 23:15:51 -0300853 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300854 struct s2255_channel *channel = fh->channel;
Hans Verkuil92513612013-02-15 06:05:08 -0300855 int is_ntsc = channel->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300856
857 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
858
859 if (fmt == NULL)
860 return -EINVAL;
861
862 field = f->fmt.pix.field;
Dean Anderson38f993a2008-06-26 23:15:51 -0300863
sensoray-devf5402002014-01-29 15:24:07 -0300864 dprintk(fh->dev, 50, "%s NTSC: %d suggested width: %d, height: %d\n",
Dean Anderson85b85482010-04-08 23:51:17 -0300865 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300866 if (is_ntsc) {
867 /* NTSC */
868 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
869 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300870 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300871 } else {
872 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
Hans Verkuil92513612013-02-15 06:05:08 -0300873 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300874 }
875 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
876 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
877 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
878 f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
879 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
880 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
881 else
882 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
883 } else {
884 /* PAL */
885 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
886 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300887 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300888 } else {
889 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300890 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300891 }
Hans Verkuil92513612013-02-15 06:05:08 -0300892 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300893 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300894 else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300895 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300896 else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300897 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300898 else
Dean Anderson38f993a2008-06-26 23:15:51 -0300899 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300900 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300901 f->fmt.pix.field = field;
902 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
903 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300904 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
905 f->fmt.pix.priv = 0;
sensoray-devf5402002014-01-29 15:24:07 -0300906 dprintk(fh->dev, 50, "%s: set width %d height %d field %d\n", __func__,
Dean Anderson85b85482010-04-08 23:51:17 -0300907 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300908 return 0;
909}
910
911static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
912 struct v4l2_format *f)
913{
914 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300915 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -0300916 const struct s2255_fmt *fmt;
917 struct videobuf_queue *q = &fh->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300918 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300919 int ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300920
921 ret = vidioc_try_fmt_vid_cap(file, fh, f);
922
923 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300924 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300925
926 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
927
928 if (fmt == NULL)
929 return -EINVAL;
930
931 mutex_lock(&q->vb_lock);
932
933 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
sensoray-devf5402002014-01-29 15:24:07 -0300934 dprintk(fh->dev, 1, "queue busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300935 ret = -EBUSY;
936 goto out_s_fmt;
937 }
938
Dean Andersonfe85ce92010-06-01 19:12:07 -0300939 if (res_locked(fh)) {
sensoray-devf5402002014-01-29 15:24:07 -0300940 dprintk(fh->dev, 1, "%s: channel busy\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -0300941 ret = -EBUSY;
942 goto out_s_fmt;
943 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300944 mode = channel->mode;
945 channel->fmt = fmt;
946 channel->width = f->fmt.pix.width;
947 channel->height = f->fmt.pix.height;
Dean Anderson38f993a2008-06-26 23:15:51 -0300948 fh->vb_vidq.field = f->fmt.pix.field;
949 fh->type = f->type;
Hans Verkuil469af772013-02-15 06:12:58 -0300950 if (channel->width > norm_minw(channel)) {
951 if (channel->height > norm_minh(channel)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300952 if (channel->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -0300953 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300954 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -0300955 else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300956 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -0300957 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300958 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300959
960 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300961 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300962 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300963 /* color mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300964 switch (channel->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300965 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300966 mode.color &= ~MASK_COLOR;
967 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -0300968 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300969 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300970 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300971 mode.color &= ~MASK_COLOR;
972 mode.color |= COLOR_JPG;
Hans Verkuil7041dec2013-02-15 05:53:45 -0300973 mode.color |= (channel->jpegqual << 8);
Dean Anderson14d96262008-08-25 13:58:55 -0300974 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300975 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300976 mode.color &= ~MASK_COLOR;
977 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300978 break;
979 case V4L2_PIX_FMT_YUYV:
980 case V4L2_PIX_FMT_UYVY:
981 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300982 mode.color &= ~MASK_COLOR;
983 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -0300984 break;
985 }
Dean Andersonfe85ce92010-06-01 19:12:07 -0300986 if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
987 mode.restart = 1;
988 else if (mode.scale != channel->mode.scale)
989 mode.restart = 1;
990 else if (mode.format != channel->mode.format)
991 mode.restart = 1;
992 channel->mode = mode;
993 (void) s2255_set_mode(channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300994 ret = 0;
995out_s_fmt:
996 mutex_unlock(&q->vb_lock);
997 return ret;
998}
999
1000static int vidioc_reqbufs(struct file *file, void *priv,
1001 struct v4l2_requestbuffers *p)
1002{
1003 int rc;
1004 struct s2255_fh *fh = priv;
1005 rc = videobuf_reqbufs(&fh->vb_vidq, p);
1006 return rc;
1007}
1008
1009static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1010{
1011 int rc;
1012 struct s2255_fh *fh = priv;
1013 rc = videobuf_querybuf(&fh->vb_vidq, p);
1014 return rc;
1015}
1016
1017static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1018{
1019 int rc;
1020 struct s2255_fh *fh = priv;
1021 rc = videobuf_qbuf(&fh->vb_vidq, p);
1022 return rc;
1023}
1024
1025static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1026{
1027 int rc;
1028 struct s2255_fh *fh = priv;
1029 rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
1030 return rc;
1031}
1032
Dean Anderson38f993a2008-06-26 23:15:51 -03001033/* write to the configuration pipe, synchronously */
1034static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
1035 int size)
1036{
1037 int pipe;
1038 int done;
1039 long retval = -1;
1040 if (udev) {
1041 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
1042 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
1043 }
1044 return retval;
1045}
1046
1047static u32 get_transfer_size(struct s2255_mode *mode)
1048{
1049 int linesPerFrame = LINE_SZ_DEF;
1050 int pixelsPerLine = NUM_LINES_DEF;
1051 u32 outImageSize;
1052 u32 usbInSize;
1053 unsigned int mask_mult;
1054
1055 if (mode == NULL)
1056 return 0;
1057
1058 if (mode->format == FORMAT_NTSC) {
1059 switch (mode->scale) {
1060 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001061 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001062 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1063 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1064 break;
1065 case SCALE_2CIFS:
1066 linesPerFrame = NUM_LINES_2CIFS_NTSC;
1067 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
1068 break;
1069 case SCALE_1CIFS:
1070 linesPerFrame = NUM_LINES_1CIFS_NTSC;
1071 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
1072 break;
1073 default:
1074 break;
1075 }
1076 } else if (mode->format == FORMAT_PAL) {
1077 switch (mode->scale) {
1078 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -03001079 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -03001080 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1081 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1082 break;
1083 case SCALE_2CIFS:
1084 linesPerFrame = NUM_LINES_2CIFS_PAL;
1085 pixelsPerLine = LINE_SZ_2CIFS_PAL;
1086 break;
1087 case SCALE_1CIFS:
1088 linesPerFrame = NUM_LINES_1CIFS_PAL;
1089 pixelsPerLine = LINE_SZ_1CIFS_PAL;
1090 break;
1091 default:
1092 break;
1093 }
1094 }
1095 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -03001096 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001097 /* 2 bytes/pixel if not monochrome */
1098 outImageSize *= 2;
1099 }
1100
1101 /* total bytes to send including prefix and 4K padding;
1102 must be a multiple of USB_READ_SIZE */
1103 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
1104 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
1105 /* if size not a multiple of USB_READ_SIZE */
1106 if (usbInSize & ~mask_mult)
1107 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
1108 return usbInSize;
1109}
1110
Dean Anderson85b85482010-04-08 23:51:17 -03001111static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -03001112{
1113 struct device *dev = &sdev->udev->dev;
1114 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -03001115 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1116 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -03001117 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -03001118 dev_info(dev, "------------------------------------------------\n");
1119}
1120
1121/*
1122 * set mode is the function which controls the DSP.
1123 * the restart parameter in struct s2255_mode should be set whenever
1124 * the image size could change via color format, video system or image
1125 * size.
1126 * When the restart parameter is set, we sleep for ONE frame to allow the
1127 * DSP time to get the new frame
1128 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001129static int s2255_set_mode(struct s2255_channel *channel,
Dean Anderson38f993a2008-06-26 23:15:51 -03001130 struct s2255_mode *mode)
1131{
1132 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001133 __le32 *buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -03001134 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001135 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001136 int i;
1137
Dean Andersonfe85ce92010-06-01 19:12:07 -03001138 chn_rev = G_chnmap[channel->idx];
sensoray-devf5402002014-01-29 15:24:07 -03001139 dprintk(dev, 3, "%s channel: %d\n", __func__, channel->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001140 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001141 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1142 mode->color &= ~MASK_COLOR;
1143 mode->color |= COLOR_JPG;
1144 mode->color &= ~MASK_JPG_QUALITY;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001145 mode->color |= (channel->jpegqual << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001146 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001147 /* save the mode */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001148 channel->mode = *mode;
1149 channel->req_image_size = get_transfer_size(mode);
sensoray-devf5402002014-01-29 15:24:07 -03001150 dprintk(dev, 1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001151 buffer = kzalloc(512, GFP_KERNEL);
1152 if (buffer == NULL) {
1153 dev_err(&dev->udev->dev, "out of mem\n");
1154 return -ENOMEM;
1155 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001156 /* set the mode */
1157 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001158 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001159 buffer[2] = CMD_SET_MODE;
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001160 for (i = 0; i < sizeof(struct s2255_mode) / sizeof(u32); i++)
1161 buffer[3 + i] = cpu_to_le32(((u32 *)&channel->mode)[i]);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001162 channel->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001163 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1164 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001165 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001166 kfree(buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03001167 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001168 if (mode->restart) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001169 wait_event_timeout(channel->wait_setmode,
1170 (channel->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001171 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001172 if (channel->setmode_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001173 dprintk(dev, 0, "s2255: no set mode response\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001174 res = -EFAULT;
1175 }
1176 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001177 /* clear the restart flag */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001178 channel->mode.restart = 0;
sensoray-devf5402002014-01-29 15:24:07 -03001179 dprintk(dev, 1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03001180 return res;
1181}
1182
Dean Andersonfe85ce92010-06-01 19:12:07 -03001183static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001184{
1185 int res;
Dean Anderson3fa00602010-03-04 20:47:33 -03001186 __le32 *buffer;
Dean Anderson4de39f52010-03-03 19:39:19 -03001187 u32 chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001188 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001189 chn_rev = G_chnmap[channel->idx];
sensoray-devf5402002014-01-29 15:24:07 -03001190 dprintk(dev, 4, "%s chan %d\n", __func__, channel->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001191 buffer = kzalloc(512, GFP_KERNEL);
1192 if (buffer == NULL) {
1193 dev_err(&dev->udev->dev, "out of mem\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001194 return -ENOMEM;
1195 }
1196 /* form the get vid status command */
1197 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001198 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001199 buffer[2] = CMD_STATUS;
1200 *pstatus = 0;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001201 channel->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001202 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1203 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001204 wait_event_timeout(channel->wait_vidstatus,
1205 (channel->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001206 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Andersonfe85ce92010-06-01 19:12:07 -03001207 if (channel->vidstatus_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001208 dprintk(dev, 0, "s2255: no vidstatus response\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001209 res = -EFAULT;
1210 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001211 *pstatus = channel->vidstatus;
sensoray-devf5402002014-01-29 15:24:07 -03001212 dprintk(dev, 4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03001213 return res;
1214}
1215
Dean Anderson38f993a2008-06-26 23:15:51 -03001216static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1217{
1218 int res;
1219 struct s2255_fh *fh = priv;
1220 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001221 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001222 int j;
sensoray-devf5402002014-01-29 15:24:07 -03001223 dprintk(dev, 4, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001224 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1225 dev_err(&dev->udev->dev, "invalid fh type0\n");
1226 return -EINVAL;
1227 }
1228 if (i != fh->type) {
1229 dev_err(&dev->udev->dev, "invalid fh type1\n");
1230 return -EINVAL;
1231 }
1232
Dean Andersonfe85ce92010-06-01 19:12:07 -03001233 if (!res_get(fh)) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001234 s2255_dev_err(&dev->udev->dev, "stream busy\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001235 return -EBUSY;
1236 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001237 channel->last_frame = -1;
1238 channel->bad_payload = 0;
1239 channel->cur_frame = 0;
1240 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001241 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001242 channel->buffer.frame[j].ulState = S2255_READ_IDLE;
1243 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001244 }
1245 res = videobuf_streamon(&fh->vb_vidq);
1246 if (res == 0) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001247 s2255_start_acquire(channel);
1248 channel->b_acquire = 1;
1249 } else
1250 res_free(fh);
1251
Dean Anderson38f993a2008-06-26 23:15:51 -03001252 return res;
1253}
1254
1255static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1256{
Dean Anderson38f993a2008-06-26 23:15:51 -03001257 struct s2255_fh *fh = priv;
sensoray-devf5402002014-01-29 15:24:07 -03001258 dprintk(fh->dev, 4, "%s\n, channel: %d", __func__, fh->channel->idx);
Dean Anderson38f993a2008-06-26 23:15:51 -03001259 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
sensoray-devf5402002014-01-29 15:24:07 -03001260 dprintk(fh->dev, 1, "invalid fh type0\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001261 return -EINVAL;
1262 }
sensoray-devf5402002014-01-29 15:24:07 -03001263 if (i != fh->type)
Dean Anderson38f993a2008-06-26 23:15:51 -03001264 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001265 s2255_stop_acquire(fh->channel);
Dean Andersonb7732a32009-03-30 11:59:56 -03001266 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001267 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001268 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001269}
1270
Hans Verkuil314527a2013-03-15 06:10:40 -03001271static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i)
Dean Anderson38f993a2008-06-26 23:15:51 -03001272{
1273 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001274 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -03001275 struct videobuf_queue *q = &fh->vb_vidq;
Hans Verkuil469af772013-02-15 06:12:58 -03001276 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001277 int ret = 0;
Hans Verkuil469af772013-02-15 06:12:58 -03001278
Dean Anderson38f993a2008-06-26 23:15:51 -03001279 mutex_lock(&q->vb_lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001280 if (res_locked(fh)) {
sensoray-devf5402002014-01-29 15:24:07 -03001281 dprintk(fh->dev, 1, "can't change standard after started\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001282 ret = -EBUSY;
1283 goto out_s_std;
1284 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001285 mode = fh->channel->mode;
Hans Verkuil314527a2013-03-15 06:10:40 -03001286 if (i & V4L2_STD_525_60) {
sensoray-devf5402002014-01-29 15:24:07 -03001287 dprintk(fh->dev, 4, "%s 60 Hz\n", __func__);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001288 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001289 if (mode.format != FORMAT_NTSC) {
1290 mode.restart = 1;
1291 mode.format = FORMAT_NTSC;
1292 mode.fdec = FDEC_1;
Hans Verkuil469af772013-02-15 06:12:58 -03001293 channel->width = LINE_SZ_4CIFS_NTSC;
1294 channel->height = NUM_LINES_4CIFS_NTSC * 2;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001295 }
Hans Verkuil314527a2013-03-15 06:10:40 -03001296 } else if (i & V4L2_STD_625_50) {
sensoray-devf5402002014-01-29 15:24:07 -03001297 dprintk(fh->dev, 4, "%s 50 Hz\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001298 if (mode.format != FORMAT_PAL) {
1299 mode.restart = 1;
1300 mode.format = FORMAT_PAL;
1301 mode.fdec = FDEC_1;
Hans Verkuil469af772013-02-15 06:12:58 -03001302 channel->width = LINE_SZ_4CIFS_PAL;
1303 channel->height = NUM_LINES_4CIFS_PAL * 2;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001304 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001305 } else {
1306 ret = -EINVAL;
Hans Verkuil469af772013-02-15 06:12:58 -03001307 goto out_s_std;
Dean Anderson38f993a2008-06-26 23:15:51 -03001308 }
Hans Verkuil314527a2013-03-15 06:10:40 -03001309 fh->channel->std = i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001310 if (mode.restart)
1311 s2255_set_mode(fh->channel, &mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001312out_s_std:
1313 mutex_unlock(&q->vb_lock);
1314 return ret;
1315}
1316
Hans Verkuil469af772013-02-15 06:12:58 -03001317static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *i)
1318{
1319 struct s2255_fh *fh = priv;
1320
1321 *i = fh->channel->std;
1322 return 0;
1323}
1324
Dean Anderson38f993a2008-06-26 23:15:51 -03001325/* Sensoray 2255 is a multiple channel capture device.
1326 It does not have a "crossbar" of inputs.
1327 We use one V4L device per channel. The user must
1328 be aware that certain combinations are not allowed.
1329 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1330 at once in color(you can do full fps on 4 channels with greyscale.
1331*/
1332static int vidioc_enum_input(struct file *file, void *priv,
1333 struct v4l2_input *inp)
1334{
Dean Anderson4de39f52010-03-03 19:39:19 -03001335 struct s2255_fh *fh = priv;
1336 struct s2255_dev *dev = fh->dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001337 struct s2255_channel *channel = fh->channel;
Dean Anderson4de39f52010-03-03 19:39:19 -03001338 u32 status = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001339 if (inp->index != 0)
1340 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001341 inp->type = V4L2_INPUT_TYPE_CAMERA;
1342 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001343 inp->status = 0;
1344 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1345 int rc;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001346 rc = s2255_cmd_status(fh->channel, &status);
sensoray-devf5402002014-01-29 15:24:07 -03001347 dprintk(dev, 4, "s2255_cmd_status rc: %d status %x\n",
1348 rc, status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001349 if (rc == 0)
1350 inp->status = (status & 0x01) ? 0
1351 : V4L2_IN_ST_NO_SIGNAL;
1352 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001353 switch (dev->pid) {
1354 case 0x2255:
1355 default:
1356 strlcpy(inp->name, "Composite", sizeof(inp->name));
1357 break;
1358 case 0x2257:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001359 strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001360 sizeof(inp->name));
1361 break;
1362 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001363 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001364}
1365
1366static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1367{
1368 *i = 0;
1369 return 0;
1370}
1371static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1372{
1373 if (i > 0)
1374 return -EINVAL;
1375 return 0;
1376}
1377
Hans Verkuil192f1e72013-02-15 05:51:21 -03001378static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
Dean Anderson38f993a2008-06-26 23:15:51 -03001379{
Hans Verkuil192f1e72013-02-15 05:51:21 -03001380 struct s2255_channel *channel =
1381 container_of(ctrl->handler, struct s2255_channel, hdl);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001382 struct s2255_mode mode;
1383 mode = channel->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001384 /* update the mode to the corresponding value */
1385 switch (ctrl->id) {
1386 case V4L2_CID_BRIGHTNESS:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001387 mode.bright = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001388 break;
1389 case V4L2_CID_CONTRAST:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001390 mode.contrast = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001391 break;
1392 case V4L2_CID_HUE:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001393 mode.hue = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001394 break;
1395 case V4L2_CID_SATURATION:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001396 mode.saturation = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001397 break;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001398 case V4L2_CID_S2255_COLORFILTER:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001399 mode.color &= ~MASK_INPUT_TYPE;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001400 mode.color |= !ctrl->val << 16;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001401 break;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001402 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1403 channel->jpegqual = ctrl->val;
1404 return 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001405 default:
1406 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001407 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001408 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001409 /* set mode here. Note: stream does not need restarted.
1410 some V4L programs restart stream unnecessarily
1411 after a s_crtl.
1412 */
Hans Verkuil192f1e72013-02-15 05:51:21 -03001413 s2255_set_mode(channel, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001414 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001415}
1416
Dean Anderson22b88d42008-08-29 15:33:19 -03001417static int vidioc_g_jpegcomp(struct file *file, void *priv,
1418 struct v4l2_jpegcompression *jc)
1419{
1420 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001421 struct s2255_channel *channel = fh->channel;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001422
1423 memset(jc, 0, sizeof(*jc));
1424 jc->quality = channel->jpegqual;
sensoray-devf5402002014-01-29 15:24:07 -03001425 dprintk(fh->dev, 2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001426 return 0;
1427}
1428
1429static int vidioc_s_jpegcomp(struct file *file, void *priv,
Hans Verkuild88aab52012-09-17 05:05:25 -03001430 const struct v4l2_jpegcompression *jc)
Dean Anderson22b88d42008-08-29 15:33:19 -03001431{
1432 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001433 struct s2255_channel *channel = fh->channel;
Dean Anderson22b88d42008-08-29 15:33:19 -03001434 if (jc->quality < 0 || jc->quality > 100)
1435 return -EINVAL;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001436 v4l2_ctrl_s_ctrl(channel->jpegqual_ctrl, jc->quality);
sensoray-devf5402002014-01-29 15:24:07 -03001437 dprintk(fh->dev, 2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001438 return 0;
1439}
Dean Anderson7d853532009-05-15 14:32:04 -03001440
1441static int vidioc_g_parm(struct file *file, void *priv,
1442 struct v4l2_streamparm *sp)
1443{
1444 struct s2255_fh *fh = priv;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001445 __u32 def_num, def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001446 struct s2255_channel *channel = fh->channel;
Dean Anderson7d853532009-05-15 14:32:04 -03001447 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1448 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001449 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001450 sp->parm.capture.capturemode = channel->cap_parm.capturemode;
1451 def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1452 def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001453 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001454 switch (channel->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001455 default:
1456 case FDEC_1:
1457 sp->parm.capture.timeperframe.numerator = def_num;
1458 break;
1459 case FDEC_2:
1460 sp->parm.capture.timeperframe.numerator = def_num * 2;
1461 break;
1462 case FDEC_3:
1463 sp->parm.capture.timeperframe.numerator = def_num * 3;
1464 break;
1465 case FDEC_5:
1466 sp->parm.capture.timeperframe.numerator = def_num * 5;
1467 break;
1468 }
sensoray-devf5402002014-01-29 15:24:07 -03001469 dprintk(fh->dev, 4, "%s capture mode, %d timeperframe %d/%d\n",
1470 __func__,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001471 sp->parm.capture.capturemode,
1472 sp->parm.capture.timeperframe.numerator,
1473 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001474 return 0;
1475}
1476
1477static int vidioc_s_parm(struct file *file, void *priv,
1478 struct v4l2_streamparm *sp)
1479{
1480 struct s2255_fh *fh = priv;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001481 struct s2255_channel *channel = fh->channel;
1482 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001483 int fdec = FDEC_1;
1484 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001485 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1486 return -EINVAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001487 mode = channel->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001488 /* high quality capture mode requires a stream restart */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001489 if (channel->cap_parm.capturemode
1490 != sp->parm.capture.capturemode && res_locked(fh))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001491 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001492 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1493 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001494 if (def_dem != sp->parm.capture.timeperframe.denominator)
1495 sp->parm.capture.timeperframe.numerator = def_num;
1496 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1497 sp->parm.capture.timeperframe.numerator = def_num;
1498 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1499 sp->parm.capture.timeperframe.numerator = def_num * 2;
1500 fdec = FDEC_2;
1501 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1502 sp->parm.capture.timeperframe.numerator = def_num * 3;
1503 fdec = FDEC_3;
1504 } else {
1505 sp->parm.capture.timeperframe.numerator = def_num * 5;
1506 fdec = FDEC_5;
1507 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001508 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001509 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001510 s2255_set_mode(channel, &mode);
sensoray-devf5402002014-01-29 15:24:07 -03001511 dprintk(fh->dev, 4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
Dean Andersone6b44bc2010-03-08 20:04:48 -03001512 __func__,
1513 sp->parm.capture.capturemode,
1514 sp->parm.capture.timeperframe.numerator,
1515 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001516 return 0;
1517}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001518
Hans Verkuil05e5d442013-02-15 06:09:18 -03001519#define NUM_SIZE_ENUMS 3
1520static const struct v4l2_frmsize_discrete ntsc_sizes[] = {
1521 { 640, 480 },
1522 { 640, 240 },
1523 { 320, 240 },
1524};
1525static const struct v4l2_frmsize_discrete pal_sizes[] = {
1526 { 704, 576 },
1527 { 704, 288 },
1528 { 352, 288 },
1529};
1530
1531static int vidioc_enum_framesizes(struct file *file, void *priv,
1532 struct v4l2_frmsizeenum *fe)
1533{
1534 struct s2255_fh *fh = priv;
1535 struct s2255_channel *channel = fh->channel;
1536 int is_ntsc = channel->std & V4L2_STD_525_60;
1537 const struct s2255_fmt *fmt;
1538
1539 if (fe->index >= NUM_SIZE_ENUMS)
1540 return -EINVAL;
1541
1542 fmt = format_by_fourcc(fe->pixel_format);
1543 if (fmt == NULL)
1544 return -EINVAL;
1545 fe->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1546 fe->discrete = is_ntsc ? ntsc_sizes[fe->index] : pal_sizes[fe->index];
1547 return 0;
1548}
1549
Dean Andersone6b44bc2010-03-08 20:04:48 -03001550static int vidioc_enum_frameintervals(struct file *file, void *priv,
1551 struct v4l2_frmivalenum *fe)
1552{
Hans Verkuil05e5d442013-02-15 06:09:18 -03001553 struct s2255_fh *fh = priv;
1554 struct s2255_channel *channel = fh->channel;
1555 const struct s2255_fmt *fmt;
1556 const struct v4l2_frmsize_discrete *sizes;
1557 int is_ntsc = channel->std & V4L2_STD_525_60;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001558#define NUM_FRAME_ENUMS 4
1559 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
Hans Verkuil05e5d442013-02-15 06:09:18 -03001560 int i;
1561
Mauro Carvalho Chehab199ab8f2012-10-27 16:29:34 -03001562 if (fe->index >= NUM_FRAME_ENUMS)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001563 return -EINVAL;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001564
1565 fmt = format_by_fourcc(fe->pixel_format);
1566 if (fmt == NULL)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001567 return -EINVAL;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001568
1569 sizes = is_ntsc ? ntsc_sizes : pal_sizes;
1570 for (i = 0; i < NUM_SIZE_ENUMS; i++, sizes++)
1571 if (fe->width == sizes->width &&
1572 fe->height == sizes->height)
1573 break;
1574 if (i == NUM_SIZE_ENUMS)
1575 return -EINVAL;
1576
Dean Andersone6b44bc2010-03-08 20:04:48 -03001577 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1578 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1579 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
sensoray-devf5402002014-01-29 15:24:07 -03001580 dprintk(fh->dev, 4, "%s discrete %d/%d\n", __func__,
1581 fe->discrete.numerator,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001582 fe->discrete.denominator);
1583 return 0;
1584}
1585
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001586static int __s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001587{
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001588 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001589 struct s2255_channel *channel = video_drvdata(file);
1590 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001591 struct s2255_fh *fh;
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02001592 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Anderson14d96262008-08-25 13:58:55 -03001593 int state;
sensoray-devf5402002014-01-29 15:24:07 -03001594 dprintk(dev, 1, "s2255: open called (dev=%s)\n",
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001595 video_device_node_name(vdev));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001596 state = atomic_read(&dev->fw_data->fw_state);
1597 switch (state) {
1598 case S2255_FW_DISCONNECTING:
Dean Andersonff7e22d2010-04-08 23:38:07 -03001599 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001600 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001601 s2255_dev_err(&dev->udev->dev,
1602 "firmware load failed. retrying.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001603 s2255_fwload_start(dev, 1);
Dean Anderson38f993a2008-06-26 23:15:51 -03001604 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001605 ((atomic_read(&dev->fw_data->fw_state)
1606 == S2255_FW_SUCCESS) ||
1607 (atomic_read(&dev->fw_data->fw_state)
1608 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001609 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001610 /* state may have changed, re-read */
1611 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001612 break;
1613 case S2255_FW_NOTLOADED:
1614 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001615 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1616 driver loaded and then device immediately opened */
sensoray-devf5402002014-01-29 15:24:07 -03001617 pr_info("%s waiting for firmware load\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001618 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001619 ((atomic_read(&dev->fw_data->fw_state)
1620 == S2255_FW_SUCCESS) ||
1621 (atomic_read(&dev->fw_data->fw_state)
1622 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001623 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001624 /* state may have changed, re-read */
1625 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001626 break;
1627 case S2255_FW_SUCCESS:
1628 default:
1629 break;
1630 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001631 /* state may have changed in above switch statement */
1632 switch (state) {
1633 case S2255_FW_SUCCESS:
1634 break;
1635 case S2255_FW_FAILED:
sensoray-devf5402002014-01-29 15:24:07 -03001636 pr_info("2255 firmware load failed.\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03001637 return -ENODEV;
1638 case S2255_FW_DISCONNECTING:
sensoray-devf5402002014-01-29 15:24:07 -03001639 pr_info("%s: disconnecting\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001640 return -ENODEV;
1641 case S2255_FW_LOADED_DSPWAIT:
1642 case S2255_FW_NOTLOADED:
sensoray-devf5402002014-01-29 15:24:07 -03001643 pr_info("%s: firmware not loaded, please retry\n",
1644 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001645 /*
1646 * Timeout on firmware load means device unusable.
1647 * Set firmware failure state.
1648 * On next s2255_open the firmware will be reloaded.
1649 */
1650 atomic_set(&dev->fw_data->fw_state,
1651 S2255_FW_FAILED);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001652 return -EAGAIN;
1653 default:
sensoray-devf5402002014-01-29 15:24:07 -03001654 pr_info("%s: unknown state\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001655 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001656 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001657 /* allocate + initialize per filehandle data */
1658 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
Dean Andersona5ef91c2010-04-08 23:46:08 -03001659 if (NULL == fh)
Dean Anderson38f993a2008-06-26 23:15:51 -03001660 return -ENOMEM;
Hans Verkuil44d06d82013-02-15 05:59:00 -03001661 v4l2_fh_init(&fh->fh, vdev);
1662 v4l2_fh_add(&fh->fh);
1663 file->private_data = &fh->fh;
Dean Anderson38f993a2008-06-26 23:15:51 -03001664 fh->dev = dev;
1665 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001666 fh->channel = channel;
1667 if (!channel->configured) {
1668 /* configure channel to default state */
1669 channel->fmt = &formats[0];
1670 s2255_set_mode(channel, &channel->mode);
1671 channel->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001672 }
sensoray-devf5402002014-01-29 15:24:07 -03001673 dprintk(dev, 1, "%s: dev=%s type=%s\n", __func__,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001674 video_device_node_name(vdev), v4l2_type_names[type]);
Dean Andersond86c6a82014-02-04 17:18:03 -03001675 dprintk(dev, 2, "%s: fh=0x%08lx, dev=0x%08lx\n", __func__,
1676 (unsigned long)fh, (unsigned long)dev);
sensoray-devf5402002014-01-29 15:24:07 -03001677 dprintk(dev, 4, "%s: list_empty active=%d\n", __func__,
Dean Andersond86c6a82014-02-04 17:18:03 -03001678 list_empty(&channel->buf_list));
Dean Anderson38f993a2008-06-26 23:15:51 -03001679 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1680 NULL, &dev->slock,
1681 fh->type,
1682 V4L2_FIELD_INTERLACED,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001683 sizeof(struct s2255_buffer),
1684 fh, vdev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001685 return 0;
1686}
1687
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001688static int s2255_open(struct file *file)
1689{
1690 struct video_device *vdev = video_devdata(file);
1691 int ret;
1692
1693 if (mutex_lock_interruptible(vdev->lock))
1694 return -ERESTARTSYS;
1695 ret = __s2255_open(file);
1696 mutex_unlock(vdev->lock);
1697 return ret;
1698}
Dean Anderson38f993a2008-06-26 23:15:51 -03001699
1700static unsigned int s2255_poll(struct file *file,
1701 struct poll_table_struct *wait)
1702{
1703 struct s2255_fh *fh = file->private_data;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001704 struct s2255_dev *dev = fh->dev;
Hans Verkuil44d06d82013-02-15 05:59:00 -03001705 int rc = v4l2_ctrl_poll(file, wait);
1706
sensoray-devf5402002014-01-29 15:24:07 -03001707 dprintk(dev, 100, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001708 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1709 return POLLERR;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001710 mutex_lock(&dev->lock);
Hans Verkuil44d06d82013-02-15 05:59:00 -03001711 rc |= videobuf_poll_stream(file, &fh->vb_vidq, wait);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001712 mutex_unlock(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001713 return rc;
1714}
1715
Dean Andersond62e85a2010-04-09 19:54:26 -03001716static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001717{
sensoray-devf5402002014-01-29 15:24:07 -03001718 dprintk(dev, 1, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001719 /* board shutdown stops the read pipe if it is running */
1720 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001721 /* make sure firmware still not trying to load */
Dean Andersonf78d92c2008-07-22 14:43:27 -03001722 del_timer(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001723 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001724 usb_kill_urb(dev->fw_data->fw_urb);
1725 usb_free_urb(dev->fw_data->fw_urb);
1726 dev->fw_data->fw_urb = NULL;
1727 }
Jesper Juhl3fc82fa2012-04-09 16:50:04 -03001728 release_firmware(dev->fw_data->fw);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001729 kfree(dev->fw_data->pfw_data);
1730 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001731 /* reset the DSP so firmware can be reloaded next time */
1732 s2255_reset_dsppower(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001733 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001734 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001735 v4l2_device_unregister(&dev->v4l2_dev);
Dean Andersonb7732a32009-03-30 11:59:56 -03001736 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001737}
1738
Dean Andersonff7e22d2010-04-08 23:38:07 -03001739static int s2255_release(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001740{
1741 struct s2255_fh *fh = file->private_data;
1742 struct s2255_dev *dev = fh->dev;
Laurent Pinchart50462eb2009-12-10 11:47:13 -02001743 struct video_device *vdev = video_devdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001744 struct s2255_channel *channel = fh->channel;
Dean Anderson38f993a2008-06-26 23:15:51 -03001745 if (!dev)
1746 return -ENODEV;
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001747 mutex_lock(&dev->lock);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001748 /* turn off stream */
1749 if (res_check(fh)) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001750 if (channel->b_acquire)
1751 s2255_stop_acquire(fh->channel);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001752 videobuf_streamoff(&fh->vb_vidq);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001753 res_free(fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001754 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001755 videobuf_mmap_free(&fh->vb_vidq);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001756 mutex_unlock(&dev->lock);
sensoray-devf5402002014-01-29 15:24:07 -03001757 dprintk(dev, 1, "%s[%s]\n", __func__, video_device_node_name(vdev));
Hans Verkuil44d06d82013-02-15 05:59:00 -03001758 v4l2_fh_del(&fh->fh);
1759 v4l2_fh_exit(&fh->fh);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001760 kfree(fh);
Dean Anderson38f993a2008-06-26 23:15:51 -03001761 return 0;
1762}
1763
1764static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1765{
1766 struct s2255_fh *fh = file->private_data;
Julia Lawalle8397762012-08-14 11:49:46 -03001767 struct s2255_dev *dev;
Dean Anderson38f993a2008-06-26 23:15:51 -03001768 int ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001769 if (!fh)
1770 return -ENODEV;
Julia Lawalle8397762012-08-14 11:49:46 -03001771 dev = fh->dev;
sensoray-devf5402002014-01-29 15:24:07 -03001772 dprintk(dev, 4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001773 if (mutex_lock_interruptible(&dev->lock))
1774 return -ERESTARTSYS;
Dean Anderson38f993a2008-06-26 23:15:51 -03001775 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
Hans Verkuil0e1f0ed2012-06-24 06:10:32 -03001776 mutex_unlock(&dev->lock);
sensoray-devf5402002014-01-29 15:24:07 -03001777 dprintk(dev, 4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
Dean Anderson38f993a2008-06-26 23:15:51 -03001778 (unsigned long)vma->vm_start,
1779 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001780 return ret;
1781}
1782
Hans Verkuilbec43662008-12-30 06:58:20 -03001783static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001784 .owner = THIS_MODULE,
1785 .open = s2255_open,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001786 .release = s2255_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001787 .poll = s2255_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001788 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
Dean Anderson38f993a2008-06-26 23:15:51 -03001789 .mmap = s2255_mmap_v4l,
Dean Anderson38f993a2008-06-26 23:15:51 -03001790};
1791
Hans Verkuila3998102008-07-21 02:57:38 -03001792static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001793 .vidioc_querycap = vidioc_querycap,
1794 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1795 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1796 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1797 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1798 .vidioc_reqbufs = vidioc_reqbufs,
1799 .vidioc_querybuf = vidioc_querybuf,
1800 .vidioc_qbuf = vidioc_qbuf,
1801 .vidioc_dqbuf = vidioc_dqbuf,
1802 .vidioc_s_std = vidioc_s_std,
Hans Verkuil469af772013-02-15 06:12:58 -03001803 .vidioc_g_std = vidioc_g_std,
Dean Anderson38f993a2008-06-26 23:15:51 -03001804 .vidioc_enum_input = vidioc_enum_input,
1805 .vidioc_g_input = vidioc_g_input,
1806 .vidioc_s_input = vidioc_s_input,
Dean Anderson38f993a2008-06-26 23:15:51 -03001807 .vidioc_streamon = vidioc_streamon,
1808 .vidioc_streamoff = vidioc_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001809 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1810 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001811 .vidioc_s_parm = vidioc_s_parm,
1812 .vidioc_g_parm = vidioc_g_parm,
Hans Verkuil05e5d442013-02-15 06:09:18 -03001813 .vidioc_enum_framesizes = vidioc_enum_framesizes,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001814 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuil44d06d82013-02-15 05:59:00 -03001815 .vidioc_log_status = v4l2_ctrl_log_status,
1816 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1817 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001818};
1819
Dean Andersonff7e22d2010-04-08 23:38:07 -03001820static void s2255_video_device_release(struct video_device *vdev)
1821{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001822 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001823 struct s2255_channel *channel =
1824 container_of(vdev, struct s2255_channel, vdev);
1825
sensoray-devf5402002014-01-29 15:24:07 -03001826 dprintk(dev, 4, "%s, chnls: %d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001827 atomic_read(&dev->num_channels));
Hans Verkuil192f1e72013-02-15 05:51:21 -03001828
sensoray-devf5402002014-01-29 15:24:07 -03001829 v4l2_ctrl_handler_free(&channel->hdl);
1830
Dean Andersonfe85ce92010-06-01 19:12:07 -03001831 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001832 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001833 return;
1834}
1835
Hans Verkuila3998102008-07-21 02:57:38 -03001836static struct video_device template = {
1837 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001838 .fops = &s2255_fops_v4l,
1839 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001840 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001841 .tvnorms = S2255_NORMS,
Dean Anderson38f993a2008-06-26 23:15:51 -03001842};
1843
Hans Verkuil192f1e72013-02-15 05:51:21 -03001844static const struct v4l2_ctrl_ops s2255_ctrl_ops = {
1845 .s_ctrl = s2255_s_ctrl,
1846};
1847
1848static const struct v4l2_ctrl_config color_filter_ctrl = {
1849 .ops = &s2255_ctrl_ops,
1850 .name = "Color Filter",
1851 .id = V4L2_CID_S2255_COLORFILTER,
1852 .type = V4L2_CTRL_TYPE_BOOLEAN,
1853 .max = 1,
1854 .step = 1,
1855 .def = 1,
1856};
1857
Dean Anderson38f993a2008-06-26 23:15:51 -03001858static int s2255_probe_v4l(struct s2255_dev *dev)
1859{
1860 int ret;
1861 int i;
1862 int cur_nr = video_nr;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001863 struct s2255_channel *channel;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001864 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1865 if (ret)
1866 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001867 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001868 /* register 4 video devices */
1869 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001870 channel = &dev->channel[i];
Dean Andersond86c6a82014-02-04 17:18:03 -03001871 INIT_LIST_HEAD(&channel->buf_list);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001872
Hans Verkuil7041dec2013-02-15 05:53:45 -03001873 v4l2_ctrl_handler_init(&channel->hdl, 6);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001874 v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops,
1875 V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT);
1876 v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops,
1877 V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST);
1878 v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops,
1879 V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION);
1880 v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops,
1881 V4L2_CID_HUE, 0, 255, 1, DEF_HUE);
Hans Verkuil7041dec2013-02-15 05:53:45 -03001882 channel->jpegqual_ctrl = v4l2_ctrl_new_std(&channel->hdl,
1883 &s2255_ctrl_ops,
1884 V4L2_CID_JPEG_COMPRESSION_QUALITY,
1885 0, 100, 1, S2255_DEF_JPEG_QUAL);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001886 if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER &&
1887 (dev->pid != 0x2257 || channel->idx <= 1))
sensoray-devf5402002014-01-29 15:24:07 -03001888 v4l2_ctrl_new_custom(&channel->hdl, &color_filter_ctrl,
1889 NULL);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001890 if (channel->hdl.error) {
1891 ret = channel->hdl.error;
1892 v4l2_ctrl_handler_free(&channel->hdl);
1893 dev_err(&dev->udev->dev, "couldn't register control\n");
1894 break;
1895 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001896 /* register 4 video devices */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001897 channel->vdev = template;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001898 channel->vdev.ctrl_handler = &channel->hdl;
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001899 channel->vdev.lock = &dev->lock;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001900 channel->vdev.v4l2_dev = &dev->v4l2_dev;
Hans Verkuil44d06d82013-02-15 05:59:00 -03001901 set_bit(V4L2_FL_USE_FH_PRIO, &channel->vdev.flags);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001902 video_set_drvdata(&channel->vdev, channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03001903 if (video_nr == -1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03001904 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001905 VFL_TYPE_GRABBER,
1906 video_nr);
1907 else
Dean Andersonfe85ce92010-06-01 19:12:07 -03001908 ret = video_register_device(&channel->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001909 VFL_TYPE_GRABBER,
1910 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001911
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001912 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001913 dev_err(&dev->udev->dev,
1914 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001915 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001916 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001917 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001918 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001919 video_device_node_name(&channel->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001920
Dean Anderson38f993a2008-06-26 23:15:51 -03001921 }
sensoray-devf5402002014-01-29 15:24:07 -03001922 pr_info("Sensoray 2255 V4L driver Revision: %s\n",
1923 S2255_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001924 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001925 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001926 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001927 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001928 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001929 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
sensoray-devf5402002014-01-29 15:24:07 -03001930 pr_warn("s2255: Not all channels available.\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001931 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001932}
1933
Dean Anderson38f993a2008-06-26 23:15:51 -03001934/* this function moves the usb stream read pipe data
1935 * into the system buffers.
1936 * returns 0 on success, EAGAIN if more data to process( call this
1937 * function again).
1938 *
1939 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001940 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001941 * bytes 4-7: channel: 0-3
1942 * bytes 8-11: payload size: size of the frame
1943 * bytes 12-payloadsize+12: frame data
1944 */
1945static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1946{
Dean Anderson38f993a2008-06-26 23:15:51 -03001947 char *pdest;
1948 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001949 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001950 char *psrc;
1951 unsigned long copy_size;
1952 unsigned long size;
1953 s32 idx = -1;
1954 struct s2255_framei *frm;
1955 unsigned char *pdata;
sensoray-devf5402002014-01-29 15:24:07 -03001956 struct s2255_channel *ch;
1957 dprintk(dev, 100, "buffer to user\n");
1958 ch = &dev->channel[dev->cc];
1959 idx = ch->cur_frame;
1960 frm = &ch->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001961 if (frm->ulState == S2255_READ_IDLE) {
1962 int jj;
1963 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03001964 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03001965 int payload;
1966 /* search for marker codes */
1967 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03001968 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03001969 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03001970 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03001971 case S2255_MARKER_FRAME:
sensoray-devf5402002014-01-29 15:24:07 -03001972 dprintk(dev, 4, "marker @ offset: %d [%x %x]\n",
1973 jj, pdata[0], pdata[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001974 offset = jj + PREFIX_SIZE;
1975 bframe = 1;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001976 cc = le32_to_cpu(pdword[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001977 if (cc >= MAX_CHANNELS) {
sensoray-devf5402002014-01-29 15:24:07 -03001978 dprintk(dev, 0,
1979 "bad channel\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001980 return -EINVAL;
1981 }
1982 /* reverse it */
1983 dev->cc = G_chnmap[cc];
sensoray-devf5402002014-01-29 15:24:07 -03001984 ch = &dev->channel[dev->cc];
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001985 payload = le32_to_cpu(pdword[3]);
sensoray-devf5402002014-01-29 15:24:07 -03001986 if (payload > ch->req_image_size) {
1987 ch->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03001988 /* discard the bad frame */
1989 return -EINVAL;
1990 }
sensoray-devf5402002014-01-29 15:24:07 -03001991 ch->pkt_size = payload;
1992 ch->jpg_size = le32_to_cpu(pdword[4]);
Dean Anderson14d96262008-08-25 13:58:55 -03001993 break;
1994 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001995
Dean Anderson14d96262008-08-25 13:58:55 -03001996 pdata += DEF_USB_BLOCK;
1997 jj += DEF_USB_BLOCK;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001998 if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001999 break;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002000 cc = G_chnmap[le32_to_cpu(pdword[1])];
Roel Kluinf14a2972009-10-23 07:59:42 -03002001 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03002002 break;
sensoray-devf5402002014-01-29 15:24:07 -03002003 ch = &dev->channel[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03002004 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03002005 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03002006 /* check if channel valid */
2007 /* set mode ready */
sensoray-devf5402002014-01-29 15:24:07 -03002008 ch->setmode_ready = 1;
2009 wake_up(&ch->wait_setmode);
2010 dprintk(dev, 5, "setmode rdy %d\n", cc);
Dean Anderson14d96262008-08-25 13:58:55 -03002011 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03002012 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03002013 dev->chn_ready |= (1 << cc);
2014 if ((dev->chn_ready & 0x0f) != 0x0f)
2015 break;
2016 /* all channels ready */
sensoray-devf5402002014-01-29 15:24:07 -03002017 pr_info("s2255: fw loaded\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002018 atomic_set(&dev->fw_data->fw_state,
2019 S2255_FW_SUCCESS);
2020 wake_up(&dev->fw_data->wait_fw);
2021 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03002022 case S2255_RESPONSE_STATUS:
sensoray-devf5402002014-01-29 15:24:07 -03002023 ch->vidstatus = le32_to_cpu(pdword[3]);
2024 ch->vidstatus_ready = 1;
2025 wake_up(&ch->wait_vidstatus);
2026 dprintk(dev, 5, "vstat %x chan %d\n",
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002027 le32_to_cpu(pdword[3]), cc);
Dean Anderson4de39f52010-03-03 19:39:19 -03002028 break;
Dean Anderson14d96262008-08-25 13:58:55 -03002029 default:
sensoray-devf5402002014-01-29 15:24:07 -03002030 pr_info("s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002031 }
2032 default:
2033 pdata++;
2034 break;
2035 }
2036 if (bframe)
2037 break;
2038 } /* for */
2039 if (!bframe)
2040 return -EINVAL;
2041 }
sensoray-devf5402002014-01-29 15:24:07 -03002042 ch = &dev->channel[dev->cc];
2043 idx = ch->cur_frame;
2044 frm = &ch->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03002045 /* search done. now find out if should be acquiring on this channel */
sensoray-devf5402002014-01-29 15:24:07 -03002046 if (!ch->b_acquire) {
Dean Anderson14d96262008-08-25 13:58:55 -03002047 /* we found a frame, but this channel is turned off */
2048 frm->ulState = S2255_READ_IDLE;
2049 return -EINVAL;
2050 }
2051
2052 if (frm->ulState == S2255_READ_IDLE) {
2053 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03002054 frm->cur_size = 0;
2055 }
2056
Dean Anderson14d96262008-08-25 13:58:55 -03002057 /* skip the marker 512 bytes (and offset if out of sync) */
2058 psrc = (u8 *)pipe_info->transfer_buffer + offset;
2059
Dean Anderson38f993a2008-06-26 23:15:51 -03002060
2061 if (frm->lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03002062 dprintk(dev, 1, "s2255 frame buffer == NULL.%p %p %d %d",
Dean Anderson38f993a2008-06-26 23:15:51 -03002063 frm, dev, dev->cc, idx);
2064 return -ENOMEM;
2065 }
2066
2067 pdest = frm->lpvbits + frm->cur_size;
2068
Dean Anderson14d96262008-08-25 13:58:55 -03002069 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03002070
sensoray-devf5402002014-01-29 15:24:07 -03002071 size = ch->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002072
Dean Anderson14d96262008-08-25 13:58:55 -03002073 /* sanity check on pdest */
sensoray-devf5402002014-01-29 15:24:07 -03002074 if ((copy_size + frm->cur_size) < ch->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03002075 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002076
Dean Anderson38f993a2008-06-26 23:15:51 -03002077 frm->cur_size += copy_size;
sensoray-devf5402002014-01-29 15:24:07 -03002078 dprintk(dev, 4, "cur_size: %lu, size: %lu\n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03002079
Dean Anderson14d96262008-08-25 13:58:55 -03002080 if (frm->cur_size >= size) {
sensoray-devf5402002014-01-29 15:24:07 -03002081 dprintk(dev, 2, "******[%d]Buffer[%d]full*******\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03002082 dev->cc, idx);
sensoray-devf5402002014-01-29 15:24:07 -03002083 ch->last_frame = ch->cur_frame;
2084 ch->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002085 /* end of system frame ring buffer, start at zero */
sensoray-devf5402002014-01-29 15:24:07 -03002086 if ((ch->cur_frame == SYS_FRAMES) ||
2087 (ch->cur_frame == ch->buffer.dwFrames))
2088 ch->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03002089 /* frame ready */
sensoray-devf5402002014-01-29 15:24:07 -03002090 if (ch->b_acquire)
2091 s2255_got_frame(ch, ch->jpg_size);
2092 ch->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03002093 frm->ulState = S2255_READ_IDLE;
2094 frm->cur_size = 0;
2095
Dean Anderson38f993a2008-06-26 23:15:51 -03002096 }
2097 /* done successfully */
2098 return 0;
2099}
2100
2101static void s2255_read_video_callback(struct s2255_dev *dev,
2102 struct s2255_pipeinfo *pipe_info)
2103{
2104 int res;
sensoray-devf5402002014-01-29 15:24:07 -03002105 dprintk(dev, 50, "callback read video\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002106
2107 if (dev->cc >= MAX_CHANNELS) {
2108 dev->cc = 0;
2109 dev_err(&dev->udev->dev, "invalid channel\n");
2110 return;
2111 }
2112 /* otherwise copy to the system buffers */
2113 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03002114 if (res != 0)
sensoray-devf5402002014-01-29 15:24:07 -03002115 dprintk(dev, 4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002116
sensoray-devf5402002014-01-29 15:24:07 -03002117 dprintk(dev, 50, "callback read video done\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002118 return;
2119}
2120
2121static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
2122 u16 Index, u16 Value, void *TransferBuffer,
2123 s32 TransferBufferLength, int bOut)
2124{
2125 int r;
2126 if (!bOut) {
2127 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
2128 Request,
2129 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
2130 USB_DIR_IN,
2131 Value, Index, TransferBuffer,
2132 TransferBufferLength, HZ * 5);
2133 } else {
2134 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
2135 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2136 Value, Index, TransferBuffer,
2137 TransferBufferLength, HZ * 5);
2138 }
2139 return r;
2140}
2141
2142/*
2143 * retrieve FX2 firmware version. future use.
2144 * @param dev pointer to device extension
2145 * @return -1 for fail, else returns firmware version as an int(16 bits)
2146 */
2147static int s2255_get_fx2fw(struct s2255_dev *dev)
2148{
2149 int fw;
2150 int ret;
2151 unsigned char transBuffer[64];
2152 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
2153 S2255_VR_IN);
2154 if (ret < 0)
sensoray-devf5402002014-01-29 15:24:07 -03002155 dprintk(dev, 2, "get fw error: %x\n", ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03002156 fw = transBuffer[0] + (transBuffer[1] << 8);
sensoray-devf5402002014-01-29 15:24:07 -03002157 dprintk(dev, 2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002158 return fw;
2159}
2160
2161/*
2162 * Create the system ring buffer to copy frames into from the
2163 * usb read pipe.
2164 */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002165static int s2255_create_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002166{
2167 unsigned long i;
2168 unsigned long reqsize;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002169 channel->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03002170 /* always allocate maximum size(PAL) for system buffers */
2171 reqsize = SYS_FRAMES_MAXSIZE;
2172
2173 if (reqsize > SYS_FRAMES_MAXSIZE)
2174 reqsize = SYS_FRAMES_MAXSIZE;
2175
2176 for (i = 0; i < SYS_FRAMES; i++) {
2177 /* allocate the frames */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002178 channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002179 channel->buffer.frame[i].size = reqsize;
2180 if (channel->buffer.frame[i].lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03002181 pr_info("out of memory. using less frames\n");
Dean Andersonfe85ce92010-06-01 19:12:07 -03002182 channel->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002183 break;
2184 }
2185 }
2186
2187 /* make sure internal states are set */
2188 for (i = 0; i < SYS_FRAMES; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002189 channel->buffer.frame[i].ulState = 0;
2190 channel->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002191 }
2192
Dean Andersonfe85ce92010-06-01 19:12:07 -03002193 channel->cur_frame = 0;
2194 channel->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002195 return 0;
2196}
2197
Dean Andersonfe85ce92010-06-01 19:12:07 -03002198static int s2255_release_sys_buffers(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002199{
2200 unsigned long i;
Dean Anderson38f993a2008-06-26 23:15:51 -03002201 for (i = 0; i < SYS_FRAMES; i++) {
sensoray-devf5402002014-01-29 15:24:07 -03002202 if (channel->buffer.frame[i].lpvbits)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002203 vfree(channel->buffer.frame[i].lpvbits);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002204 channel->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002205 }
2206 return 0;
2207}
2208
2209static int s2255_board_init(struct s2255_dev *dev)
2210{
Dean Anderson38f993a2008-06-26 23:15:51 -03002211 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2212 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002213 int j;
2214 struct s2255_pipeinfo *pipe = &dev->pipe;
sensoray-devf5402002014-01-29 15:24:07 -03002215 dprintk(dev, 4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002216 memset(pipe, 0, sizeof(*pipe));
2217 pipe->dev = dev;
2218 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2219 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03002220
Dean Andersonab85c6a2010-04-08 23:39:12 -03002221 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2222 GFP_KERNEL);
2223 if (pipe->transfer_buffer == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03002224 dprintk(dev, 1, "out of memory!\n");
Dean Andersonab85c6a2010-04-08 23:39:12 -03002225 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002226 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002227 /* query the firmware */
2228 fw_ver = s2255_get_fx2fw(dev);
2229
sensoray-devf5402002014-01-29 15:24:07 -03002230 pr_info("s2255: usb firmware version %d.%d\n",
2231 (fw_ver >> 8) & 0xff,
2232 fw_ver & 0xff);
Dean Andersonabce21f2009-04-23 16:04:41 -03002233
2234 if (fw_ver < S2255_CUR_USB_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002235 pr_info("s2255: newer USB firmware available\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002236
2237 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002238 struct s2255_channel *channel = &dev->channel[j];
2239 channel->b_acquire = 0;
2240 channel->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002241 if (dev->pid == 0x2257 && j > 1)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002242 channel->mode.color |= (1 << 16);
Hans Verkuil7041dec2013-02-15 05:53:45 -03002243 channel->jpegqual = S2255_DEF_JPEG_QUAL;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002244 channel->width = LINE_SZ_4CIFS_NTSC;
2245 channel->height = NUM_LINES_4CIFS_NTSC * 2;
Hans Verkuil469af772013-02-15 06:12:58 -03002246 channel->std = V4L2_STD_NTSC_M;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002247 channel->fmt = &formats[0];
2248 channel->mode.restart = 1;
2249 channel->req_image_size = get_transfer_size(&mode_def);
2250 channel->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002251 /* create the system buffers */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002252 s2255_create_sys_buffers(channel);
Dean Anderson38f993a2008-06-26 23:15:51 -03002253 }
2254 /* start read pipe */
2255 s2255_start_readpipe(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002256 dprintk(dev, 1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002257 return 0;
2258}
2259
2260static int s2255_board_shutdown(struct s2255_dev *dev)
2261{
2262 u32 i;
sensoray-devf5402002014-01-29 15:24:07 -03002263 dprintk(dev, 1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002264
2265 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002266 if (dev->channel[i].b_acquire)
2267 s2255_stop_acquire(&dev->channel[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002268 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002269 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002270 for (i = 0; i < MAX_CHANNELS; i++)
Dean Andersonfe85ce92010-06-01 19:12:07 -03002271 s2255_release_sys_buffers(&dev->channel[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002272 /* release transfer buffer */
2273 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002274 return 0;
2275}
2276
2277static void read_pipe_completion(struct urb *purb)
2278{
2279 struct s2255_pipeinfo *pipe_info;
2280 struct s2255_dev *dev;
2281 int status;
2282 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002283 pipe_info = purb->context;
Dean Anderson38f993a2008-06-26 23:15:51 -03002284 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002285 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002286 return;
2287 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002288 dev = pipe_info->dev;
2289 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002290 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002291 return;
2292 }
2293 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002294 /* if shutting down, do not resubmit, exit immediately */
2295 if (status == -ESHUTDOWN) {
sensoray-devf5402002014-01-29 15:24:07 -03002296 dprintk(dev, 2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002297 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002298 return;
2299 }
2300
2301 if (pipe_info->state == 0) {
sensoray-devf5402002014-01-29 15:24:07 -03002302 dprintk(dev, 2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002303 return;
2304 }
2305
Dean Andersonb02064c2009-04-30 12:29:38 -03002306 if (status == 0)
2307 s2255_read_video_callback(dev, pipe_info);
2308 else {
2309 pipe_info->err_count++;
sensoray-devf5402002014-01-29 15:24:07 -03002310 dprintk(dev, 1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002311 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002312
Dean Anderson38f993a2008-06-26 23:15:51 -03002313 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2314 /* reuse urb */
2315 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2316 pipe,
2317 pipe_info->transfer_buffer,
2318 pipe_info->cur_transfer_size,
2319 read_pipe_completion, pipe_info);
2320
2321 if (pipe_info->state != 0) {
sensoray-devf5402002014-01-29 15:24:07 -03002322 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC))
Dean Anderson38f993a2008-06-26 23:15:51 -03002323 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002324 } else {
sensoray-devf5402002014-01-29 15:24:07 -03002325 dprintk(dev, 2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002326 }
2327 return;
2328}
2329
2330static int s2255_start_readpipe(struct s2255_dev *dev)
2331{
2332 int pipe;
2333 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002334 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002335 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
sensoray-devf5402002014-01-29 15:24:07 -03002336 dprintk(dev, 2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002337 pipe_info->state = 1;
2338 pipe_info->err_count = 0;
2339 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2340 if (!pipe_info->stream_urb) {
2341 dev_err(&dev->udev->dev,
2342 "ReadStream: Unable to alloc URB\n");
2343 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002344 }
Dean Andersonab85c6a2010-04-08 23:39:12 -03002345 /* transfer buffer allocated in board_init */
2346 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2347 pipe,
2348 pipe_info->transfer_buffer,
2349 pipe_info->cur_transfer_size,
2350 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002351 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2352 if (retval) {
sensoray-devf5402002014-01-29 15:24:07 -03002353 pr_err("s2255: start read pipe failed\n");
Dean Andersonab85c6a2010-04-08 23:39:12 -03002354 return retval;
2355 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002356 return 0;
2357}
2358
2359/* starts acquisition process */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002360static int s2255_start_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002361{
2362 unsigned char *buffer;
2363 int res;
2364 unsigned long chn_rev;
2365 int j;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002366 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2367 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002368 buffer = kzalloc(512, GFP_KERNEL);
2369 if (buffer == NULL) {
2370 dev_err(&dev->udev->dev, "out of mem\n");
2371 return -ENOMEM;
2372 }
2373
Dean Andersonfe85ce92010-06-01 19:12:07 -03002374 channel->last_frame = -1;
2375 channel->bad_payload = 0;
2376 channel->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002377 for (j = 0; j < SYS_FRAMES; j++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002378 channel->buffer.frame[j].ulState = 0;
2379 channel->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002380 }
2381
2382 /* send the start command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002383 *(__le32 *) buffer = IN_DATA_TOKEN;
2384 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2385 *((__le32 *) buffer + 2) = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002386 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2387 if (res != 0)
2388 dev_err(&dev->udev->dev, "CMD_START error\n");
2389
sensoray-devf5402002014-01-29 15:24:07 -03002390 dprintk(dev, 2, "start acquire exit[%d] %d\n", channel->idx, res);
Dean Anderson38f993a2008-06-26 23:15:51 -03002391 kfree(buffer);
2392 return 0;
2393}
2394
Dean Andersonfe85ce92010-06-01 19:12:07 -03002395static int s2255_stop_acquire(struct s2255_channel *channel)
Dean Anderson38f993a2008-06-26 23:15:51 -03002396{
2397 unsigned char *buffer;
2398 int res;
2399 unsigned long chn_rev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002400 struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
2401 chn_rev = G_chnmap[channel->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002402 buffer = kzalloc(512, GFP_KERNEL);
2403 if (buffer == NULL) {
2404 dev_err(&dev->udev->dev, "out of mem\n");
2405 return -ENOMEM;
2406 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002407 /* send the stop command */
Dean Anderson3fa00602010-03-04 20:47:33 -03002408 *(__le32 *) buffer = IN_DATA_TOKEN;
2409 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2410 *((__le32 *) buffer + 2) = CMD_STOP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002411 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002412 if (res != 0)
2413 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002414 kfree(buffer);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002415 channel->b_acquire = 0;
sensoray-devf5402002014-01-29 15:24:07 -03002416 dprintk(dev, 4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
Dean Anderson14d96262008-08-25 13:58:55 -03002417 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002418}
2419
2420static void s2255_stop_readpipe(struct s2255_dev *dev)
2421{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002422 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002423
Dean Andersonab85c6a2010-04-08 23:39:12 -03002424 pipe->state = 0;
2425 if (pipe->stream_urb) {
2426 /* cancel urb */
2427 usb_kill_urb(pipe->stream_urb);
2428 usb_free_urb(pipe->stream_urb);
2429 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002430 }
sensoray-devf5402002014-01-29 15:24:07 -03002431 dprintk(dev, 4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002432 return;
2433}
2434
Dean Anderson14d96262008-08-25 13:58:55 -03002435static void s2255_fwload_start(struct s2255_dev *dev, int reset)
Dean Anderson38f993a2008-06-26 23:15:51 -03002436{
Dean Anderson14d96262008-08-25 13:58:55 -03002437 if (reset)
2438 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002439 dev->fw_data->fw_size = dev->fw_data->fw->size;
2440 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2441 memcpy(dev->fw_data->pfw_data,
2442 dev->fw_data->fw->data, CHUNK_SIZE);
2443 dev->fw_data->fw_loaded = CHUNK_SIZE;
2444 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2445 usb_sndbulkpipe(dev->udev, 2),
2446 dev->fw_data->pfw_data,
2447 CHUNK_SIZE, s2255_fwchunk_complete,
2448 dev->fw_data);
2449 mod_timer(&dev->timer, jiffies + HZ);
2450}
2451
2452/* standard usb probe function */
2453static int s2255_probe(struct usb_interface *interface,
2454 const struct usb_device_id *id)
2455{
2456 struct s2255_dev *dev = NULL;
2457 struct usb_host_interface *iface_desc;
2458 struct usb_endpoint_descriptor *endpoint;
2459 int i;
2460 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002461 __le32 *pdata;
2462 int fw_size;
Dean Anderson38f993a2008-06-26 23:15:51 -03002463 /* allocate memory for our device state and initialize it to zero */
2464 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2465 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002466 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002467 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002468 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002469 atomic_set(&dev->num_channels, 0);
Hans Verkuil0b84caa2013-02-26 14:14:19 -03002470 dev->pid = le16_to_cpu(id->idProduct);
Dean Anderson38f993a2008-06-26 23:15:51 -03002471 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2472 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002473 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002474 mutex_init(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002475 /* grab usb_device and save it */
2476 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2477 if (dev->udev == NULL) {
2478 dev_err(&interface->dev, "null usb device\n");
2479 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002480 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002481 }
sensoray-devf5402002014-01-29 15:24:07 -03002482 dev_dbg(&interface->dev, "dev: %p, udev %p interface %p\n",
2483 dev, dev->udev, interface);
Dean Anderson38f993a2008-06-26 23:15:51 -03002484 dev->interface = interface;
2485 /* set up the endpoint information */
2486 iface_desc = interface->cur_altsetting;
sensoray-devf5402002014-01-29 15:24:07 -03002487 dev_dbg(&interface->dev, "num EP: %d\n",
2488 iface_desc->desc.bNumEndpoints);
Dean Anderson38f993a2008-06-26 23:15:51 -03002489 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2490 endpoint = &iface_desc->endpoint[i].desc;
2491 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2492 /* we found the bulk in endpoint */
2493 dev->read_endpoint = endpoint->bEndpointAddress;
2494 }
2495 }
2496
2497 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002498 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002499 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002500 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002501 init_timer(&dev->timer);
2502 dev->timer.function = s2255_timer;
2503 dev->timer.data = (unsigned long)dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -03002504 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002505 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002506 struct s2255_channel *channel = &dev->channel[i];
sensoray-devf5402002014-01-29 15:24:07 -03002507 channel->idx = i;
2508 channel->dev = dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002509 init_waitqueue_head(&channel->wait_setmode);
2510 init_waitqueue_head(&channel->wait_vidstatus);
Dean Anderson4de39f52010-03-03 19:39:19 -03002511 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002512
2513 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Dean Anderson38f993a2008-06-26 23:15:51 -03002514 if (!dev->fw_data->fw_urb) {
2515 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002516 goto errorFWURB;
Dean Anderson38f993a2008-06-26 23:15:51 -03002517 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03002518
Dean Anderson38f993a2008-06-26 23:15:51 -03002519 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2520 if (!dev->fw_data->pfw_data) {
2521 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002522 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002523 }
2524 /* load the first chunk */
2525 if (request_firmware(&dev->fw_data->fw,
2526 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
sensoray-devf5402002014-01-29 15:24:07 -03002527 dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002528 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002529 }
Dean Anderson14d96262008-08-25 13:58:55 -03002530 /* check the firmware is valid */
2531 fw_size = dev->fw_data->fw->size;
2532 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002533
Dean Anderson14d96262008-08-25 13:58:55 -03002534 if (*pdata != S2255_FW_MARKER) {
sensoray-devf5402002014-01-29 15:24:07 -03002535 dev_err(&interface->dev, "Firmware invalid.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002536 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002537 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002538 } else {
2539 /* make sure firmware is the latest */
2540 __le32 *pRel;
2541 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
sensoray-devf5402002014-01-29 15:24:07 -03002542 pr_info("s2255 dsp fw version %x\n", le32_to_cpu(*pRel));
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002543 dev->dsp_fw_ver = le32_to_cpu(*pRel);
2544 if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002545 pr_info("s2255: f2255usb.bin out of date.\n");
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002546 if (dev->pid == 0x2257 &&
2547 dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
sensoray-devf5402002014-01-29 15:24:07 -03002548 pr_warn("2257 needs firmware %d or above.\n",
2549 S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002550 }
Dean Anderson14d96262008-08-25 13:58:55 -03002551 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002552 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002553 retval = s2255_board_init(dev);
2554 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002555 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002556 spin_lock_init(&dev->slock);
Dean Anderson14d96262008-08-25 13:58:55 -03002557 s2255_fwload_start(dev, 0);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002558 /* loads v4l specific */
2559 retval = s2255_probe_v4l(dev);
2560 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002561 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002562 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2563 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002564errorBOARDINIT:
2565 s2255_board_shutdown(dev);
2566errorFWMARKER:
2567 release_firmware(dev->fw_data->fw);
2568errorREQFW:
2569 kfree(dev->fw_data->pfw_data);
2570errorFWDATA2:
2571 usb_free_urb(dev->fw_data->fw_urb);
2572errorFWURB:
2573 del_timer(&dev->timer);
2574errorEP:
2575 usb_put_dev(dev->udev);
2576errorUDEV:
2577 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002578 mutex_destroy(&dev->lock);
2579errorFWDATA1:
2580 kfree(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002581 pr_warn("Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002582 return retval;
2583}
2584
2585/* disconnect routine. when board is removed physically or with rmmod */
2586static void s2255_disconnect(struct usb_interface *interface)
2587{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002588 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002589 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002590 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002591 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002592 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002593 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002594 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002595 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002596 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002597 for (i = 0; i < channels; i++)
2598 video_unregister_device(&dev->channel[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002599 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002600 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2601 wake_up(&dev->fw_data->wait_fw);
2602 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03002603 dev->channel[i].setmode_ready = 1;
2604 wake_up(&dev->channel[i].wait_setmode);
2605 dev->channel[i].vidstatus_ready = 1;
2606 wake_up(&dev->channel[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002607 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002608 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002609 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002610 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002611}
2612
2613static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002614 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002615 .probe = s2255_probe,
2616 .disconnect = s2255_disconnect,
2617 .id_table = s2255_table,
2618};
2619
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002620module_usb_driver(s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002621
2622MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2623MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2624MODULE_LICENSE("GPL");
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03002625MODULE_VERSION(S2255_VERSION);
Tim Gardner1bec9822012-07-24 16:52:27 -03002626MODULE_FIRMWARE(FIRMWARE_FILE_NAME);