blob: 3eccbd48bdac2740507db0bf60497e4c1f106c5b [file] [log] [blame]
Thomas Gleixnerc942fdd2019-05-27 08:55:06 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Dean Anderson38f993a2008-06-26 23:15:51 -03002/*
3 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
4 *
Dean Andersond86c6a82014-02-04 17:18:03 -03005 * Copyright (C) 2007-2014 by Sensoray Company Inc.
Dean Anderson38f993a2008-06-26 23:15:51 -03006 * Dean Anderson
7 *
8 * Some video buffer code based on vivi driver:
9 *
10 * Sensoray 2255 device supports 4 simultaneous channels.
11 * The channels are not "crossbar" inputs, they are physically
12 * attached to separate video decoders.
13 *
14 * Because of USB2.0 bandwidth limitations. There is only a
15 * certain amount of data which may be transferred at one time.
16 *
17 * Example maximum bandwidth utilization:
18 *
19 * -full size, color mode YUYV or YUV422P: 2 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030020 * -full or half size Grey scale: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030021 * -half size, color mode YUYV or YUV422P: all 4 channels at once
Dean Anderson38f993a2008-06-26 23:15:51 -030022 * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
23 * at once.
Dean Anderson38f993a2008-06-26 23:15:51 -030024 */
25
26#include <linux/module.h>
27#include <linux/firmware.h>
28#include <linux/kernel.h>
29#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090030#include <linux/slab.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030031#include <linux/videodev2.h>
Hans Verkuilfeb75f02008-07-27 06:30:21 -030032#include <linux/mm.h>
Hans Verkuil44d06d82013-02-15 05:59:00 -030033#include <linux/vmalloc.h>
34#include <linux/usb.h>
Junghak Sung2d700712015-09-22 10:30:30 -030035#include <media/videobuf2-v4l2.h>
sensoray-dev340a30c2014-02-12 17:25:45 -030036#include <media/videobuf2-vmalloc.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030037#include <media/v4l2-common.h>
Dean Anderson3a67b5cc2010-04-08 23:52:20 -030038#include <media/v4l2-device.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030039#include <media/v4l2-ioctl.h>
Hans Verkuil192f1e72013-02-15 05:51:21 -030040#include <media/v4l2-ctrls.h>
Hans Verkuil44d06d82013-02-15 05:59:00 -030041#include <media/v4l2-event.h>
Dean Anderson38f993a2008-06-26 23:15:51 -030042
sensoray-dev340a30c2014-02-12 17:25:45 -030043#define S2255_VERSION "1.25.1"
Dean Anderson38f993a2008-06-26 23:15:51 -030044#define FIRMWARE_FILE_NAME "f2255usb.bin"
45
Dean Anderson22b88d42008-08-29 15:33:19 -030046/* default JPEG quality */
47#define S2255_DEF_JPEG_QUAL 50
Dean Anderson38f993a2008-06-26 23:15:51 -030048/* vendor request in */
49#define S2255_VR_IN 0
50/* vendor request out */
51#define S2255_VR_OUT 1
52/* firmware query */
53#define S2255_VR_FW 0x30
54/* USB endpoint number for configuring the device */
55#define S2255_CONFIG_EP 2
56/* maximum time for DSP to start responding after last FW word loaded(ms) */
Dean Anderson14d96262008-08-25 13:58:55 -030057#define S2255_DSP_BOOTTIME 800
Dean Anderson38f993a2008-06-26 23:15:51 -030058/* maximum time to wait for firmware to load (ms) */
Dean Anderson3f8d6f72008-06-30 21:28:34 -030059#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
Dean Anderson9da62eb2014-02-05 14:58:06 -030060#define S2255_MIN_BUFS 2
Dean Anderson14d96262008-08-25 13:58:55 -030061#define S2255_SETMODE_TIMEOUT 500
Dean Anderson4de39f52010-03-03 19:39:19 -030062#define S2255_VIDSTATUS_TIMEOUT 350
Dean Anderson3fa00602010-03-04 20:47:33 -030063#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
64#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
65#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
66#define S2255_RESPONSE_FW cpu_to_le32(0x10)
67#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
Dean Anderson14d96262008-08-25 13:58:55 -030068#define S2255_USB_XFER_SIZE (16 * 1024)
Dean Anderson38f993a2008-06-26 23:15:51 -030069#define MAX_CHANNELS 4
Dean Anderson38f993a2008-06-26 23:15:51 -030070#define SYS_FRAMES 4
71/* maximum size is PAL full size plus room for the marker header(s) */
Dean Anderson14d96262008-08-25 13:58:55 -030072#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
73#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
Dean Anderson38f993a2008-06-26 23:15:51 -030074#define LINE_SZ_4CIFS_NTSC 640
75#define LINE_SZ_2CIFS_NTSC 640
76#define LINE_SZ_1CIFS_NTSC 320
77#define LINE_SZ_4CIFS_PAL 704
78#define LINE_SZ_2CIFS_PAL 704
79#define LINE_SZ_1CIFS_PAL 352
80#define NUM_LINES_4CIFS_NTSC 240
81#define NUM_LINES_2CIFS_NTSC 240
82#define NUM_LINES_1CIFS_NTSC 240
83#define NUM_LINES_4CIFS_PAL 288
84#define NUM_LINES_2CIFS_PAL 288
85#define NUM_LINES_1CIFS_PAL 288
86#define LINE_SZ_DEF 640
87#define NUM_LINES_DEF 240
88
89
90/* predefined settings */
91#define FORMAT_NTSC 1
92#define FORMAT_PAL 2
93
94#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
95#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
96#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
Dean Anderson7d853532009-05-15 14:32:04 -030097/* SCALE_4CIFSI is the 2 fields interpolated into one */
98#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
Dean Anderson38f993a2008-06-26 23:15:51 -030099
100#define COLOR_YUVPL 1 /* YUV planar */
101#define COLOR_YUVPK 2 /* YUV packed */
102#define COLOR_Y8 4 /* monochrome */
Dean Anderson14d96262008-08-25 13:58:55 -0300103#define COLOR_JPG 5 /* JPEG */
Dean Anderson38f993a2008-06-26 23:15:51 -0300104
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300105#define MASK_COLOR 0x000000ff
106#define MASK_JPG_QUALITY 0x0000ff00
107#define MASK_INPUT_TYPE 0x000f0000
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300108/* frame decimation. */
Dean Anderson38f993a2008-06-26 23:15:51 -0300109#define FDEC_1 1 /* capture every frame. default */
110#define FDEC_2 2 /* capture every 2nd frame */
111#define FDEC_3 3 /* capture every 3rd frame */
112#define FDEC_5 5 /* capture every 5th frame */
113
114/*-------------------------------------------------------
115 * Default mode parameters.
116 *-------------------------------------------------------*/
117#define DEF_SCALE SCALE_4CIFS
118#define DEF_COLOR COLOR_YUVPL
119#define DEF_FDEC FDEC_1
120#define DEF_BRIGHT 0
121#define DEF_CONTRAST 0x5c
122#define DEF_SATURATION 0x80
123#define DEF_HUE 0
124
125/* usb config commands */
Dean Anderson3fa00602010-03-04 20:47:33 -0300126#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
Dan Carpenter3b2a6302012-02-17 02:44:10 -0300127#define CMD_2255 0xc2255000
Dean Anderson3fa00602010-03-04 20:47:33 -0300128#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
129#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
130#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
131#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
Dean Anderson38f993a2008-06-26 23:15:51 -0300132
133struct s2255_mode {
134 u32 format; /* input video format (NTSC, PAL) */
135 u32 scale; /* output video scale */
136 u32 color; /* output video color format */
137 u32 fdec; /* frame decimation */
138 u32 bright; /* brightness */
139 u32 contrast; /* contrast */
140 u32 saturation; /* saturation */
141 u32 hue; /* hue (NTSC only)*/
142 u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
143 u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
144 u32 restart; /* if DSP requires restart */
145};
146
Dean Anderson14d96262008-08-25 13:58:55 -0300147
148#define S2255_READ_IDLE 0
149#define S2255_READ_FRAME 1
150
Dean Anderson38f993a2008-06-26 23:15:51 -0300151/* frame structure */
Dean Anderson38f993a2008-06-26 23:15:51 -0300152struct s2255_framei {
153 unsigned long size;
Dean Anderson14d96262008-08-25 13:58:55 -0300154 unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300155 void *lpvbits; /* image data */
156 unsigned long cur_size; /* current data copied to it */
157};
158
159/* image buffer structure */
160struct s2255_bufferi {
161 unsigned long dwFrames; /* number of frames in buffer */
162 struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
163};
164
165#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
166 DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300167 DEF_HUE, 0, DEF_USB_BLOCK, 0}
Dean Anderson38f993a2008-06-26 23:15:51 -0300168
Dean Anderson38f993a2008-06-26 23:15:51 -0300169/* for firmware loading, fw_state */
170#define S2255_FW_NOTLOADED 0
171#define S2255_FW_LOADED_DSPWAIT 1
172#define S2255_FW_SUCCESS 2
173#define S2255_FW_FAILED 3
Dean Andersonf78d92c2008-07-22 14:43:27 -0300174#define S2255_FW_DISCONNECTING 4
Harvey Harrisondeaf53e2008-11-15 01:10:14 -0300175#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
Dean Anderson14d96262008-08-25 13:58:55 -0300176/* 2255 read states */
177#define S2255_READ_IDLE 0
178#define S2255_READ_FRAME 1
Dean Anderson38f993a2008-06-26 23:15:51 -0300179struct s2255_fw {
180 int fw_loaded;
181 int fw_size;
182 struct urb *fw_urb;
183 atomic_t fw_state;
184 void *pfw_data;
185 wait_queue_head_t wait_fw;
Dean Anderson38f993a2008-06-26 23:15:51 -0300186 const struct firmware *fw;
187};
188
189struct s2255_pipeinfo {
190 u32 max_transfer_size;
191 u32 cur_transfer_size;
192 u8 *transfer_buffer;
Dean Anderson38f993a2008-06-26 23:15:51 -0300193 u32 state;
Dean Anderson38f993a2008-06-26 23:15:51 -0300194 void *stream_urb;
195 void *dev; /* back pointer to s2255_dev struct*/
196 u32 err_count;
Dean Anderson38f993a2008-06-26 23:15:51 -0300197 u32 idx;
Dean Anderson38f993a2008-06-26 23:15:51 -0300198};
199
200struct s2255_fmt; /*forward declaration */
Dean Andersonfe85ce92010-06-01 19:12:07 -0300201struct s2255_dev;
202
Dean Anderson5e950fa2014-02-04 18:16:24 -0300203/* 2255 video channel */
204struct s2255_vc {
sensoray-devf5402002014-01-29 15:24:07 -0300205 struct s2255_dev *dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300206 struct video_device vdev;
Hans Verkuil192f1e72013-02-15 05:51:21 -0300207 struct v4l2_ctrl_handler hdl;
Hans Verkuil7041dec2013-02-15 05:53:45 -0300208 struct v4l2_ctrl *jpegqual_ctrl;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300209 int resources;
Dean Andersond86c6a82014-02-04 17:18:03 -0300210 struct list_head buf_list;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300211 struct s2255_bufferi buffer;
212 struct s2255_mode mode;
Hans Verkuil469af772013-02-15 06:12:58 -0300213 v4l2_std_id std;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300214 /* jpeg compression */
Hans Verkuil7041dec2013-02-15 05:53:45 -0300215 unsigned jpegqual;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300216 /* capture parameters (for high quality mode full size) */
217 struct v4l2_captureparm cap_parm;
218 int cur_frame;
219 int last_frame;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300220 /* allocated image size */
221 unsigned long req_image_size;
222 /* received packet size */
223 unsigned long pkt_size;
224 int bad_payload;
225 unsigned long frame_count;
226 /* if JPEG image */
227 int jpg_size;
228 /* if channel configured to default state */
229 int configured;
230 wait_queue_head_t wait_setmode;
231 int setmode_ready;
232 /* video status items */
233 int vidstatus;
234 wait_queue_head_t wait_vidstatus;
235 int vidstatus_ready;
236 unsigned int width;
237 unsigned int height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300238 enum v4l2_field field;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300239 const struct s2255_fmt *fmt;
240 int idx; /* channel number on device, 0-3 */
sensoray-dev340a30c2014-02-12 17:25:45 -0300241 struct vb2_queue vb_vidq;
242 struct mutex vb_lock; /* streaming lock */
243 spinlock_t qlock;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300244};
245
Dean Anderson38f993a2008-06-26 23:15:51 -0300246
247struct s2255_dev {
Dean Anderson5e950fa2014-02-04 18:16:24 -0300248 struct s2255_vc vc[MAX_CHANNELS];
sensoray-devf5402002014-01-29 15:24:07 -0300249 struct v4l2_device v4l2_dev;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300250 atomic_t num_channels;
Dean Anderson38f993a2008-06-26 23:15:51 -0300251 int frames;
Pete Eberleina19a5cd2010-12-20 19:18:59 -0300252 struct mutex lock; /* channels[].vdev.lock */
Dean Anderson47d8c882014-02-05 15:43:51 -0300253 struct mutex cmdlock; /* protects cmdbuf */
Dean Anderson38f993a2008-06-26 23:15:51 -0300254 struct usb_device *udev;
255 struct usb_interface *interface;
256 u8 read_endpoint;
Dean Anderson38f993a2008-06-26 23:15:51 -0300257 struct timer_list timer;
258 struct s2255_fw *fw_data;
Dean Andersonab85c6a2010-04-08 23:39:12 -0300259 struct s2255_pipeinfo pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -0300260 u32 cc; /* current channel */
Dean Anderson38f993a2008-06-26 23:15:51 -0300261 int frame_ready;
Dean Anderson14d96262008-08-25 13:58:55 -0300262 int chn_ready;
Dean Anderson4de39f52010-03-03 19:39:19 -0300263 /* dsp firmware version (f2255usb.bin) */
264 int dsp_fw_ver;
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300265 u16 pid; /* product id */
Dean Anderson47d8c882014-02-05 15:43:51 -0300266#define S2255_CMDBUF_SIZE 512
267 __le32 *cmdbuf;
Dean Anderson38f993a2008-06-26 23:15:51 -0300268};
Dean Anderson65c6edb2010-04-20 17:21:32 -0300269
Dean Anderson65c6edb2010-04-20 17:21:32 -0300270static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
271{
272 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
273}
Dean Anderson38f993a2008-06-26 23:15:51 -0300274
275struct s2255_fmt {
276 char *name;
277 u32 fourcc;
278 int depth;
279};
280
281/* buffer for one video frame */
282struct s2255_buffer {
283 /* common v4l buffer stuff -- must be first */
Junghak Sung2d700712015-09-22 10:30:30 -0300284 struct vb2_v4l2_buffer vb;
sensoray-dev340a30c2014-02-12 17:25:45 -0300285 struct list_head list;
Dean Anderson38f993a2008-06-26 23:15:51 -0300286};
287
Dean Anderson38f993a2008-06-26 23:15:51 -0300288
Dean Andersonabce21f2009-04-23 16:04:41 -0300289/* current cypress EEPROM firmware version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300290#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
Dean Anderson4de39f52010-03-03 19:39:19 -0300291/* current DSP FW version */
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300292#define S2255_CUR_DSP_FWVER 10104
Dean Anderson4de39f52010-03-03 19:39:19 -0300293/* Need DSP version 5+ for video status feature */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300294#define S2255_MIN_DSP_STATUS 5
295#define S2255_MIN_DSP_COLORFILTER 8
Hans Verkuil469af772013-02-15 06:12:58 -0300296#define S2255_NORMS (V4L2_STD_ALL)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300297
298/* private V4L2 controls */
299
300/*
301 * The following chart displays how COLORFILTER should be set
302 * =========================================================
303 * = fourcc = COLORFILTER =
304 * = ===============================
305 * = = 0 = 1 =
306 * =========================================================
307 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
308 * = = s-video or = composite =
309 * = = B/W camera = input =
310 * =========================================================
311 * = other = color, svideo = color, =
312 * = = = composite =
313 * =========================================================
314 *
315 * Notes:
316 * channels 0-3 on 2255 are composite
317 * channels 0-1 on 2257 are composite, 2-3 are s-video
318 * If COLORFILTER is 0 with a composite color camera connected,
319 * the output will appear monochrome but hatching
320 * will occur.
321 * COLORFILTER is different from "color killer" and "color effects"
322 * for reasons above.
323 */
324#define S2255_V4L2_YC_ON 1
325#define S2255_V4L2_YC_OFF 0
Hans Verkuil192f1e72013-02-15 05:51:21 -0300326#define V4L2_CID_S2255_COLORFILTER (V4L2_CID_USER_S2255_BASE + 0)
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300327
Dean Anderson38f993a2008-06-26 23:15:51 -0300328/* frame prefix size (sent once every frame) */
329#define PREFIX_SIZE 512
330
331/* Channels on box are in reverse order */
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300332static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
Dean Anderson38f993a2008-06-26 23:15:51 -0300333
Dean Anderson38f993a2008-06-26 23:15:51 -0300334static int debug;
Dean Anderson38f993a2008-06-26 23:15:51 -0300335
336static int s2255_start_readpipe(struct s2255_dev *dev);
337static void s2255_stop_readpipe(struct s2255_dev *dev);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300338static int s2255_start_acquire(struct s2255_vc *vc);
339static int s2255_stop_acquire(struct s2255_vc *vc);
340static void s2255_fillbuff(struct s2255_vc *vc, struct s2255_buffer *buf,
Dean Andersonfe85ce92010-06-01 19:12:07 -0300341 int jpgsize);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300342static int s2255_set_mode(struct s2255_vc *vc, struct s2255_mode *mode);
Dean Anderson38f993a2008-06-26 23:15:51 -0300343static int s2255_board_shutdown(struct s2255_dev *dev);
Dean Ae2a06702017-11-03 16:11:03 -0400344static void s2255_fwload_start(struct s2255_dev *dev);
Dean Andersond62e85a2010-04-09 19:54:26 -0300345static void s2255_destroy(struct s2255_dev *dev);
Dean Anderson14d96262008-08-25 13:58:55 -0300346static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
347 u16 index, u16 value, void *buf,
348 s32 buf_len, int bOut);
Dean Anderson38f993a2008-06-26 23:15:51 -0300349
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300350/* dev_err macro with driver name */
351#define S2255_DRIVER_NAME "s2255"
352#define s2255_dev_err(dev, fmt, arg...) \
353 dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
354
sensoray-devf5402002014-01-29 15:24:07 -0300355#define dprintk(dev, level, fmt, arg...) \
356 v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
Dean Anderson38f993a2008-06-26 23:15:51 -0300357
Dean Anderson38f993a2008-06-26 23:15:51 -0300358static struct usb_driver s2255_driver;
359
Dean Anderson38f993a2008-06-26 23:15:51 -0300360/* start video number */
361static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
362
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300363/* Enable jpeg capture. */
364static int jpeg_enable = 1;
365
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300366module_param(debug, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300367MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300368module_param(video_nr, int, 0644);
Dean Anderson38f993a2008-06-26 23:15:51 -0300369MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300370module_param(jpeg_enable, int, 0644);
371MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
Dean Anderson38f993a2008-06-26 23:15:51 -0300372
373/* USB device table */
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300374#define USB_SENSORAY_VID 0x1943
Arvind Yadav7fb2e072017-08-13 04:54:43 -0400375static const struct usb_device_id s2255_table[] = {
Dean Anderson5a34d9d2010-03-05 19:59:48 -0300376 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
377 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
Dean Anderson38f993a2008-06-26 23:15:51 -0300378 { } /* Terminating entry */
379};
380MODULE_DEVICE_TABLE(usb, s2255_table);
381
Dean Anderson38f993a2008-06-26 23:15:51 -0300382#define BUFFER_TIMEOUT msecs_to_jiffies(400)
383
Dean Anderson38f993a2008-06-26 23:15:51 -0300384/* image formats. */
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300385/* JPEG formats must be defined last to support jpeg_enable parameter */
Dean Anderson38f993a2008-06-26 23:15:51 -0300386static const struct s2255_fmt formats[] = {
387 {
Dean Anderson38f993a2008-06-26 23:15:51 -0300388 .name = "4:2:2, packed, YUYV",
389 .fourcc = V4L2_PIX_FMT_YUYV,
390 .depth = 16
391
392 }, {
393 .name = "4:2:2, packed, UYVY",
394 .fourcc = V4L2_PIX_FMT_UYVY,
395 .depth = 16
396 }, {
Hans Verkuil5c632b22013-02-26 14:29:04 -0300397 .name = "4:2:2, planar, YUV422P",
398 .fourcc = V4L2_PIX_FMT_YUV422P,
399 .depth = 16
400
401 }, {
Sensoray Linux Developmente42e28f2011-04-04 15:23:03 -0300402 .name = "8bpp GREY",
403 .fourcc = V4L2_PIX_FMT_GREY,
404 .depth = 8
405 }, {
Dean Anderson14d96262008-08-25 13:58:55 -0300406 .name = "JPG",
407 .fourcc = V4L2_PIX_FMT_JPEG,
408 .depth = 24
409 }, {
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300410 .name = "MJPG",
411 .fourcc = V4L2_PIX_FMT_MJPEG,
412 .depth = 24
Dean Anderson38f993a2008-06-26 23:15:51 -0300413 }
414};
415
Dean Anderson5e950fa2014-02-04 18:16:24 -0300416static int norm_maxw(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300417{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300418 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300419 LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
420}
421
Dean Anderson5e950fa2014-02-04 18:16:24 -0300422static int norm_maxh(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300423{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300424 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300425 (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
426}
427
Dean Anderson5e950fa2014-02-04 18:16:24 -0300428static int norm_minw(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300429{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300430 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300431 LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
432}
433
Dean Anderson5e950fa2014-02-04 18:16:24 -0300434static int norm_minh(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -0300435{
Dean Anderson5e950fa2014-02-04 18:16:24 -0300436 return (vc->std & V4L2_STD_525_60) ?
Dean Anderson38f993a2008-06-26 23:15:51 -0300437 (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
438}
439
440
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300441/*
442 * TODO: fixme: move YUV reordering to hardware
443 * converts 2255 planar format to yuyv or uyvy
444 */
Dean Anderson38f993a2008-06-26 23:15:51 -0300445static void planar422p_to_yuv_packed(const unsigned char *in,
446 unsigned char *out,
447 int width, int height,
448 int fmt)
449{
450 unsigned char *pY;
451 unsigned char *pCb;
452 unsigned char *pCr;
453 unsigned long size = height * width;
454 unsigned int i;
455 pY = (unsigned char *)in;
456 pCr = (unsigned char *)in + height * width;
457 pCb = (unsigned char *)in + height * width + (height * width / 2);
458 for (i = 0; i < size * 2; i += 4) {
459 out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
460 out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
461 out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
462 out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
463 }
464 return;
465}
466
Hans Verkuild45b9b82008-09-04 03:33:43 -0300467static void s2255_reset_dsppower(struct s2255_dev *dev)
Dean Anderson14d96262008-08-25 13:58:55 -0300468{
Sensoray Linux Development8a8cc952011-04-04 14:08:40 -0300469 s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
Dean Ae2a06702017-11-03 16:11:03 -0400470 msleep(50);
Dean Anderson14d96262008-08-25 13:58:55 -0300471 s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
sensoray-dev752eb7a2011-01-19 17:41:45 -0300472 msleep(600);
473 s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
Dean Anderson14d96262008-08-25 13:58:55 -0300474 return;
475}
Dean Anderson38f993a2008-06-26 23:15:51 -0300476
477/* kickstarts the firmware loading. from probe
478 */
Kees Cook74ee0472017-10-24 11:23:21 -0400479static void s2255_timer(struct timer_list *t)
Dean Anderson38f993a2008-06-26 23:15:51 -0300480{
Kees Cook74ee0472017-10-24 11:23:21 -0400481 struct s2255_dev *dev = from_timer(dev, t, timer);
482 struct s2255_fw *data = dev->fw_data;
Dean Anderson38f993a2008-06-26 23:15:51 -0300483 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
sensoray-devf5402002014-01-29 15:24:07 -0300484 pr_err("s2255: can't submit urb\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300485 atomic_set(&data->fw_state, S2255_FW_FAILED);
486 /* wake up anything waiting for the firmware */
487 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300488 return;
489 }
490}
491
Dean Anderson38f993a2008-06-26 23:15:51 -0300492
493/* this loads the firmware asynchronously.
Hans Verkuil0b84caa2013-02-26 14:14:19 -0300494 Originally this was done synchronously in probe.
Dean Anderson38f993a2008-06-26 23:15:51 -0300495 But it is better to load it asynchronously here than block
496 inside the probe function. Blocking inside probe affects boot time.
497 FW loading is triggered by the timer in the probe function
498*/
499static void s2255_fwchunk_complete(struct urb *urb)
500{
501 struct s2255_fw *data = urb->context;
502 struct usb_device *udev = urb->dev;
503 int len;
Dean Anderson38f993a2008-06-26 23:15:51 -0300504 if (urb->status) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300505 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
Dean Andersonf78d92c2008-07-22 14:43:27 -0300506 atomic_set(&data->fw_state, S2255_FW_FAILED);
507 /* wake up anything waiting for the firmware */
508 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300509 return;
510 }
511 if (data->fw_urb == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -0300512 s2255_dev_err(&udev->dev, "disconnected\n");
Dean Andersonf78d92c2008-07-22 14:43:27 -0300513 atomic_set(&data->fw_state, S2255_FW_FAILED);
514 /* wake up anything waiting for the firmware */
515 wake_up(&data->wait_fw);
Dean Anderson38f993a2008-06-26 23:15:51 -0300516 return;
517 }
518#define CHUNK_SIZE 512
519 /* all USB transfers must be done with continuous kernel memory.
520 can't allocate more than 128k in current linux kernel, so
521 upload the firmware in chunks
522 */
523 if (data->fw_loaded < data->fw_size) {
524 len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
525 data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
526
527 if (len < CHUNK_SIZE)
528 memset(data->pfw_data, 0, CHUNK_SIZE);
529
Dean Anderson38f993a2008-06-26 23:15:51 -0300530 memcpy(data->pfw_data,
531 (char *) data->fw->data + data->fw_loaded, len);
532
533 usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
534 data->pfw_data, CHUNK_SIZE,
535 s2255_fwchunk_complete, data);
536 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
537 dev_err(&udev->dev, "failed submit URB\n");
538 atomic_set(&data->fw_state, S2255_FW_FAILED);
539 /* wake up anything waiting for the firmware */
540 wake_up(&data->wait_fw);
541 return;
542 }
543 data->fw_loaded += len;
sensoray-devf5402002014-01-29 15:24:07 -0300544 } else
Dean Anderson38f993a2008-06-26 23:15:51 -0300545 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
Dean Anderson38f993a2008-06-26 23:15:51 -0300546 return;
547
548}
549
sensoray-dev9694fbe2014-11-04 17:34:03 -0300550static void s2255_got_frame(struct s2255_vc *vc, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300551{
Dean Anderson38f993a2008-06-26 23:15:51 -0300552 struct s2255_buffer *buf;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300553 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson38f993a2008-06-26 23:15:51 -0300554 unsigned long flags = 0;
sensoray-dev9694fbe2014-11-04 17:34:03 -0300555
sensoray-dev340a30c2014-02-12 17:25:45 -0300556 spin_lock_irqsave(&vc->qlock, flags);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300557 if (list_empty(&vc->buf_list)) {
sensoray-devf5402002014-01-29 15:24:07 -0300558 dprintk(dev, 1, "No active queue to serve\n");
sensoray-dev9694fbe2014-11-04 17:34:03 -0300559 spin_unlock_irqrestore(&vc->qlock, flags);
560 return;
Dean Anderson38f993a2008-06-26 23:15:51 -0300561 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300562 buf = list_entry(vc->buf_list.next,
sensoray-dev340a30c2014-02-12 17:25:45 -0300563 struct s2255_buffer, list);
564 list_del(&buf->list);
Junghak Sungd6dd6452015-11-03 08:16:37 -0200565 buf->vb.vb2_buf.timestamp = ktime_get_ns();
Junghak Sung2d700712015-09-22 10:30:30 -0300566 buf->vb.field = vc->field;
567 buf->vb.sequence = vc->frame_count;
sensoray-dev340a30c2014-02-12 17:25:45 -0300568 spin_unlock_irqrestore(&vc->qlock, flags);
sensoray-dev9694fbe2014-11-04 17:34:03 -0300569
570 s2255_fillbuff(vc, buf, jpgsize);
571 /* tell v4l buffer was filled */
Junghak Sung2d700712015-09-22 10:30:30 -0300572 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
sensoray-dev9694fbe2014-11-04 17:34:03 -0300573 dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf);
Dean Anderson38f993a2008-06-26 23:15:51 -0300574}
575
Dean Anderson38f993a2008-06-26 23:15:51 -0300576static const struct s2255_fmt *format_by_fourcc(int fourcc)
577{
578 unsigned int i;
Dean Anderson38f993a2008-06-26 23:15:51 -0300579 for (i = 0; i < ARRAY_SIZE(formats); i++) {
580 if (-1 == formats[i].fourcc)
581 continue;
sensoray-devf5402002014-01-29 15:24:07 -0300582 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
583 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
584 continue;
Dean Anderson38f993a2008-06-26 23:15:51 -0300585 if (formats[i].fourcc == fourcc)
586 return formats + i;
587 }
588 return NULL;
589}
590
Dean Anderson38f993a2008-06-26 23:15:51 -0300591/* video buffer vmalloc implementation based partly on VIVI driver which is
592 * Copyright (c) 2006 by
593 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
594 * Ted Walther <ted--a.t--enumera.com>
595 * John Sokol <sokol--a.t--videotechnology.com>
596 * http://v4l.videotechnology.com/
597 *
598 */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300599static void s2255_fillbuff(struct s2255_vc *vc,
Dean Andersonfe85ce92010-06-01 19:12:07 -0300600 struct s2255_buffer *buf, int jpgsize)
Dean Anderson38f993a2008-06-26 23:15:51 -0300601{
602 int pos = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300603 const char *tmpbuf;
Junghak Sung2d700712015-09-22 10:30:30 -0300604 char *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
Dean Anderson38f993a2008-06-26 23:15:51 -0300605 unsigned long last_frame;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300606 struct s2255_dev *dev = vc->dev;
Dean Anderson38f993a2008-06-26 23:15:51 -0300607
608 if (!vbuf)
609 return;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300610 last_frame = vc->last_frame;
Dean Anderson38f993a2008-06-26 23:15:51 -0300611 if (last_frame != -1) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300612 tmpbuf =
Dean Anderson5e950fa2014-02-04 18:16:24 -0300613 (const char *)vc->buffer.frame[last_frame].lpvbits;
Dean Anderson8bf405a2014-02-05 15:18:55 -0300614 switch (vc->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300615 case V4L2_PIX_FMT_YUYV:
616 case V4L2_PIX_FMT_UYVY:
617 planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
sensoray-dev340a30c2014-02-12 17:25:45 -0300618 vbuf, vc->width,
619 vc->height,
Dean Anderson8bf405a2014-02-05 15:18:55 -0300620 vc->fmt->fourcc);
Dean Anderson38f993a2008-06-26 23:15:51 -0300621 break;
622 case V4L2_PIX_FMT_GREY:
sensoray-dev340a30c2014-02-12 17:25:45 -0300623 memcpy(vbuf, tmpbuf, vc->width * vc->height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300624 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300625 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300626 case V4L2_PIX_FMT_MJPEG:
Junghak Sung2d700712015-09-22 10:30:30 -0300627 vb2_set_plane_payload(&buf->vb.vb2_buf, 0, jpgsize);
sensoray-dev340a30c2014-02-12 17:25:45 -0300628 memcpy(vbuf, tmpbuf, jpgsize);
Dean Anderson14d96262008-08-25 13:58:55 -0300629 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300630 case V4L2_PIX_FMT_YUV422P:
631 memcpy(vbuf, tmpbuf,
sensoray-dev340a30c2014-02-12 17:25:45 -0300632 vc->width * vc->height * 2);
Dean Anderson38f993a2008-06-26 23:15:51 -0300633 break;
634 default:
sensoray-devf5402002014-01-29 15:24:07 -0300635 pr_info("s2255: unknown format?\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300636 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300637 vc->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -0300638 } else {
sensoray-devf5402002014-01-29 15:24:07 -0300639 pr_err("s2255: =======no frame\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300640 return;
Dean Anderson38f993a2008-06-26 23:15:51 -0300641 }
Mauro Carvalho Chehab86f181c2018-03-23 06:56:55 -0400642 dprintk(dev, 2, "s2255fill at : Buffer %p size= %d\n",
643 vbuf, pos);
Dean Anderson38f993a2008-06-26 23:15:51 -0300644}
645
646
647/* ------------------------------------------------------------------
648 Videobuf operations
649 ------------------------------------------------------------------*/
650
Hans Verkuildf9ecb02015-10-28 00:50:37 -0200651static int queue_setup(struct vb2_queue *vq,
sensoray-dev340a30c2014-02-12 17:25:45 -0300652 unsigned int *nbuffers, unsigned int *nplanes,
Hans Verkuil36c0f8b2016-04-15 09:15:05 -0300653 unsigned int sizes[], struct device *alloc_devs[])
Dean Anderson38f993a2008-06-26 23:15:51 -0300654{
sensoray-dev340a30c2014-02-12 17:25:45 -0300655 struct s2255_vc *vc = vb2_get_drv_priv(vq);
Dean Anderson9da62eb2014-02-05 14:58:06 -0300656 if (*nbuffers < S2255_MIN_BUFS)
657 *nbuffers = S2255_MIN_BUFS;
sensoray-dev340a30c2014-02-12 17:25:45 -0300658 *nplanes = 1;
659 sizes[0] = vc->width * vc->height * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300660 return 0;
661}
662
sensoray-dev340a30c2014-02-12 17:25:45 -0300663static int buffer_prepare(struct vb2_buffer *vb)
Dean Anderson38f993a2008-06-26 23:15:51 -0300664{
sensoray-dev340a30c2014-02-12 17:25:45 -0300665 struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
Junghak Sung2d700712015-09-22 10:30:30 -0300666 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
667 struct s2255_buffer *buf = container_of(vbuf, struct s2255_buffer, vb);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300668 int w = vc->width;
669 int h = vc->height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300670 unsigned long size;
671
672 dprintk(vc->dev, 4, "%s\n", __func__);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300673 if (vc->fmt == NULL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300674 return -EINVAL;
675
Dean Anderson5e950fa2014-02-04 18:16:24 -0300676 if ((w < norm_minw(vc)) ||
677 (w > norm_maxw(vc)) ||
678 (h < norm_minh(vc)) ||
679 (h > norm_maxh(vc))) {
Dean Anderson92cde472014-02-05 17:38:42 -0300680 dprintk(vc->dev, 4, "invalid buffer prepare\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300681 return -EINVAL;
682 }
sensoray-dev340a30c2014-02-12 17:25:45 -0300683 size = w * h * (vc->fmt->depth >> 3);
684 if (vb2_plane_size(vb, 0) < size) {
Dean Anderson92cde472014-02-05 17:38:42 -0300685 dprintk(vc->dev, 4, "invalid buffer prepare\n");
Dean Anderson38f993a2008-06-26 23:15:51 -0300686 return -EINVAL;
687 }
688
Junghak Sung2d700712015-09-22 10:30:30 -0300689 vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
Dean Anderson38f993a2008-06-26 23:15:51 -0300690 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300691}
692
sensoray-dev340a30c2014-02-12 17:25:45 -0300693static void buffer_queue(struct vb2_buffer *vb)
Dean Anderson38f993a2008-06-26 23:15:51 -0300694{
Junghak Sung2d700712015-09-22 10:30:30 -0300695 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
696 struct s2255_buffer *buf = container_of(vbuf, struct s2255_buffer, vb);
sensoray-dev340a30c2014-02-12 17:25:45 -0300697 struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
698 unsigned long flags = 0;
Dean Anderson92cde472014-02-05 17:38:42 -0300699 dprintk(vc->dev, 1, "%s\n", __func__);
sensoray-dev340a30c2014-02-12 17:25:45 -0300700 spin_lock_irqsave(&vc->qlock, flags);
701 list_add_tail(&buf->list, &vc->buf_list);
702 spin_unlock_irqrestore(&vc->qlock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -0300703}
704
sensoray-dev340a30c2014-02-12 17:25:45 -0300705static int start_streaming(struct vb2_queue *vq, unsigned int count);
Hans Verkuile37559b2014-04-17 02:47:21 -0300706static void stop_streaming(struct vb2_queue *vq);
Dean Anderson38f993a2008-06-26 23:15:51 -0300707
Julia Lawall1bc17712016-09-08 20:59:01 -0300708static const struct vb2_ops s2255_video_qops = {
sensoray-dev340a30c2014-02-12 17:25:45 -0300709 .queue_setup = queue_setup,
Dean Anderson38f993a2008-06-26 23:15:51 -0300710 .buf_prepare = buffer_prepare,
711 .buf_queue = buffer_queue,
sensoray-dev340a30c2014-02-12 17:25:45 -0300712 .start_streaming = start_streaming,
713 .stop_streaming = stop_streaming,
714 .wait_prepare = vb2_ops_wait_prepare,
715 .wait_finish = vb2_ops_wait_finish,
Dean Anderson38f993a2008-06-26 23:15:51 -0300716};
717
Dean Anderson38f993a2008-06-26 23:15:51 -0300718static int vidioc_querycap(struct file *file, void *priv,
719 struct v4l2_capability *cap)
720{
sensoray-dev340a30c2014-02-12 17:25:45 -0300721 struct s2255_vc *vc = video_drvdata(file);
722 struct s2255_dev *dev = vc->dev;
Hans Verkuil39696002013-02-07 07:06:21 -0300723
Mauro Carvalho Chehabc0decac2018-09-10 08:19:14 -0400724 strscpy(cap->driver, "s2255", sizeof(cap->driver));
725 strscpy(cap->card, "s2255", sizeof(cap->card));
Thierry MERLEe22ed882009-01-20 18:19:25 -0300726 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
sensoray-dev340a30c2014-02-12 17:25:45 -0300727 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
728 V4L2_CAP_READWRITE;
Hans Verkuil39696002013-02-07 07:06:21 -0300729 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300730 return 0;
731}
732
733static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
734 struct v4l2_fmtdesc *f)
735{
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300736 int index = f->index;
Dean Anderson38f993a2008-06-26 23:15:51 -0300737
738 if (index >= ARRAY_SIZE(formats))
739 return -EINVAL;
Dan Carpenter6c61ac632012-02-17 02:43:27 -0300740 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
741 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
742 return -EINVAL;
Mauro Carvalho Chehabc0decac2018-09-10 08:19:14 -0400743 strscpy(f->description, formats[index].name, sizeof(f->description));
Dean Anderson38f993a2008-06-26 23:15:51 -0300744 f->pixelformat = formats[index].fourcc;
745 return 0;
746}
747
748static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
749 struct v4l2_format *f)
750{
sensoray-dev340a30c2014-02-12 17:25:45 -0300751 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300752 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300753
Dean Anderson5e950fa2014-02-04 18:16:24 -0300754 f->fmt.pix.width = vc->width;
755 f->fmt.pix.height = vc->height;
Hans Verkuil92513612013-02-15 06:05:08 -0300756 if (f->fmt.pix.height >=
757 (is_ntsc ? NUM_LINES_1CIFS_NTSC : NUM_LINES_1CIFS_PAL) * 2)
758 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
759 else
760 f->fmt.pix.field = V4L2_FIELD_TOP;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300761 f->fmt.pix.pixelformat = vc->fmt->fourcc;
762 f->fmt.pix.bytesperline = f->fmt.pix.width * (vc->fmt->depth >> 3);
Dean Anderson38f993a2008-06-26 23:15:51 -0300763 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300764 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
765 f->fmt.pix.priv = 0;
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300766 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300767}
768
769static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
770 struct v4l2_format *f)
771{
772 const struct s2255_fmt *fmt;
773 enum v4l2_field field;
sensoray-dev340a30c2014-02-12 17:25:45 -0300774 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -0300775 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Anderson38f993a2008-06-26 23:15:51 -0300776
777 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
778
779 if (fmt == NULL)
780 return -EINVAL;
781
782 field = f->fmt.pix.field;
Dean Anderson38f993a2008-06-26 23:15:51 -0300783
Dean Anderson92cde472014-02-05 17:38:42 -0300784 dprintk(vc->dev, 50, "%s NTSC: %d suggested width: %d, height: %d\n",
Dean Anderson85b85482010-04-08 23:51:17 -0300785 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
Dean Anderson38f993a2008-06-26 23:15:51 -0300786 if (is_ntsc) {
787 /* NTSC */
788 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
789 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300790 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300791 } else {
792 f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
Hans Verkuil92513612013-02-15 06:05:08 -0300793 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300794 }
795 if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
796 f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
Dean Anderson38f993a2008-06-26 23:15:51 -0300797 else
798 f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
799 } else {
800 /* PAL */
801 if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
802 f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
Hans Verkuil92513612013-02-15 06:05:08 -0300803 field = V4L2_FIELD_INTERLACED;
Dean Anderson38f993a2008-06-26 23:15:51 -0300804 } else {
805 f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300806 field = V4L2_FIELD_TOP;
Dean Anderson38f993a2008-06-26 23:15:51 -0300807 }
Hans Verkuil92513612013-02-15 06:05:08 -0300808 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL)
Dean Anderson38f993a2008-06-26 23:15:51 -0300809 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
Hans Verkuil92513612013-02-15 06:05:08 -0300810 else
Dean Anderson38f993a2008-06-26 23:15:51 -0300811 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300812 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300813 f->fmt.pix.field = field;
814 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
815 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
Hans Verkuil29ceb112013-02-15 06:03:26 -0300816 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
817 f->fmt.pix.priv = 0;
Dean Anderson92cde472014-02-05 17:38:42 -0300818 dprintk(vc->dev, 50, "%s: set width %d height %d field %d\n", __func__,
Dean Anderson85b85482010-04-08 23:51:17 -0300819 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
Dean Anderson38f993a2008-06-26 23:15:51 -0300820 return 0;
821}
822
823static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
824 struct v4l2_format *f)
825{
sensoray-dev340a30c2014-02-12 17:25:45 -0300826 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson38f993a2008-06-26 23:15:51 -0300827 const struct s2255_fmt *fmt;
sensoray-dev340a30c2014-02-12 17:25:45 -0300828 struct vb2_queue *q = &vc->vb_vidq;
Dean Andersonfe85ce92010-06-01 19:12:07 -0300829 struct s2255_mode mode;
Dean Anderson38f993a2008-06-26 23:15:51 -0300830 int ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300831
sensoray-dev340a30c2014-02-12 17:25:45 -0300832 ret = vidioc_try_fmt_vid_cap(file, vc, f);
Dean Anderson38f993a2008-06-26 23:15:51 -0300833
834 if (ret < 0)
Dean Anderson3f8d6f72008-06-30 21:28:34 -0300835 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -0300836
837 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
838
839 if (fmt == NULL)
840 return -EINVAL;
841
sensoray-dev340a30c2014-02-12 17:25:45 -0300842 if (vb2_is_busy(q)) {
Dean Anderson92cde472014-02-05 17:38:42 -0300843 dprintk(vc->dev, 1, "queue busy\n");
sensoray-dev340a30c2014-02-12 17:25:45 -0300844 return -EBUSY;
Dean Anderson38f993a2008-06-26 23:15:51 -0300845 }
846
Dean Anderson5e950fa2014-02-04 18:16:24 -0300847 mode = vc->mode;
848 vc->fmt = fmt;
849 vc->width = f->fmt.pix.width;
850 vc->height = f->fmt.pix.height;
sensoray-dev340a30c2014-02-12 17:25:45 -0300851 vc->field = f->fmt.pix.field;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300852 if (vc->width > norm_minw(vc)) {
853 if (vc->height > norm_minh(vc)) {
854 if (vc->cap_parm.capturemode &
Dean Anderson85b85482010-04-08 23:51:17 -0300855 V4L2_MODE_HIGHQUALITY)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300856 mode.scale = SCALE_4CIFSI;
Dean Anderson85b85482010-04-08 23:51:17 -0300857 else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300858 mode.scale = SCALE_4CIFS;
Dean Anderson7d853532009-05-15 14:32:04 -0300859 } else
Dean Andersonfe85ce92010-06-01 19:12:07 -0300860 mode.scale = SCALE_2CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300861
862 } else {
Dean Andersonfe85ce92010-06-01 19:12:07 -0300863 mode.scale = SCALE_1CIFS;
Dean Anderson38f993a2008-06-26 23:15:51 -0300864 }
Dean Anderson38f993a2008-06-26 23:15:51 -0300865 /* color mode */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300866 switch (vc->fmt->fourcc) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300867 case V4L2_PIX_FMT_GREY:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300868 mode.color &= ~MASK_COLOR;
869 mode.color |= COLOR_Y8;
Dean Anderson38f993a2008-06-26 23:15:51 -0300870 break;
Dean Anderson14d96262008-08-25 13:58:55 -0300871 case V4L2_PIX_FMT_JPEG:
Sensoray Linux Developmentd0ef8542011-04-04 15:16:26 -0300872 case V4L2_PIX_FMT_MJPEG:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300873 mode.color &= ~MASK_COLOR;
874 mode.color |= COLOR_JPG;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300875 mode.color |= (vc->jpegqual << 8);
Dean Anderson14d96262008-08-25 13:58:55 -0300876 break;
Dean Anderson38f993a2008-06-26 23:15:51 -0300877 case V4L2_PIX_FMT_YUV422P:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300878 mode.color &= ~MASK_COLOR;
879 mode.color |= COLOR_YUVPL;
Dean Anderson38f993a2008-06-26 23:15:51 -0300880 break;
881 case V4L2_PIX_FMT_YUYV:
882 case V4L2_PIX_FMT_UYVY:
883 default:
Dean Andersonfe85ce92010-06-01 19:12:07 -0300884 mode.color &= ~MASK_COLOR;
885 mode.color |= COLOR_YUVPK;
Dean Anderson38f993a2008-06-26 23:15:51 -0300886 break;
887 }
Dean Anderson5e950fa2014-02-04 18:16:24 -0300888 if ((mode.color & MASK_COLOR) != (vc->mode.color & MASK_COLOR))
Dean Andersonfe85ce92010-06-01 19:12:07 -0300889 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300890 else if (mode.scale != vc->mode.scale)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300891 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300892 else if (mode.format != vc->mode.format)
Dean Andersonfe85ce92010-06-01 19:12:07 -0300893 mode.restart = 1;
Dean Anderson5e950fa2014-02-04 18:16:24 -0300894 vc->mode = mode;
895 (void) s2255_set_mode(vc, &mode);
sensoray-dev340a30c2014-02-12 17:25:45 -0300896 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -0300897}
898
Dean Anderson38f993a2008-06-26 23:15:51 -0300899
Dean Anderson38f993a2008-06-26 23:15:51 -0300900/* write to the configuration pipe, synchronously */
901static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
902 int size)
903{
904 int pipe;
905 int done;
906 long retval = -1;
907 if (udev) {
908 pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
909 retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
910 }
911 return retval;
912}
913
914static u32 get_transfer_size(struct s2255_mode *mode)
915{
916 int linesPerFrame = LINE_SZ_DEF;
917 int pixelsPerLine = NUM_LINES_DEF;
918 u32 outImageSize;
919 u32 usbInSize;
920 unsigned int mask_mult;
921
922 if (mode == NULL)
923 return 0;
924
925 if (mode->format == FORMAT_NTSC) {
926 switch (mode->scale) {
927 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -0300928 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -0300929 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
930 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
931 break;
932 case SCALE_2CIFS:
933 linesPerFrame = NUM_LINES_2CIFS_NTSC;
934 pixelsPerLine = LINE_SZ_2CIFS_NTSC;
935 break;
936 case SCALE_1CIFS:
937 linesPerFrame = NUM_LINES_1CIFS_NTSC;
938 pixelsPerLine = LINE_SZ_1CIFS_NTSC;
939 break;
940 default:
941 break;
942 }
943 } else if (mode->format == FORMAT_PAL) {
944 switch (mode->scale) {
945 case SCALE_4CIFS:
Dean Anderson7d853532009-05-15 14:32:04 -0300946 case SCALE_4CIFSI:
Dean Anderson38f993a2008-06-26 23:15:51 -0300947 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
948 pixelsPerLine = LINE_SZ_4CIFS_PAL;
949 break;
950 case SCALE_2CIFS:
951 linesPerFrame = NUM_LINES_2CIFS_PAL;
952 pixelsPerLine = LINE_SZ_2CIFS_PAL;
953 break;
954 case SCALE_1CIFS:
955 linesPerFrame = NUM_LINES_1CIFS_PAL;
956 pixelsPerLine = LINE_SZ_1CIFS_PAL;
957 break;
958 default:
959 break;
960 }
961 }
962 outImageSize = linesPerFrame * pixelsPerLine;
Dean Anderson14d96262008-08-25 13:58:55 -0300963 if ((mode->color & MASK_COLOR) != COLOR_Y8) {
Dean Anderson38f993a2008-06-26 23:15:51 -0300964 /* 2 bytes/pixel if not monochrome */
965 outImageSize *= 2;
966 }
967
968 /* total bytes to send including prefix and 4K padding;
969 must be a multiple of USB_READ_SIZE */
970 usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
971 mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
972 /* if size not a multiple of USB_READ_SIZE */
973 if (usbInSize & ~mask_mult)
974 usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
975 return usbInSize;
976}
977
Dean Anderson85b85482010-04-08 23:51:17 -0300978static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
Dean Anderson38f993a2008-06-26 23:15:51 -0300979{
980 struct device *dev = &sdev->udev->dev;
981 dev_info(dev, "------------------------------------------------\n");
Dean Anderson85b85482010-04-08 23:51:17 -0300982 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
983 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
Dean Anderson38f993a2008-06-26 23:15:51 -0300984 dev_info(dev, "bright: 0x%x\n", mode->bright);
Dean Anderson38f993a2008-06-26 23:15:51 -0300985 dev_info(dev, "------------------------------------------------\n");
986}
987
988/*
989 * set mode is the function which controls the DSP.
990 * the restart parameter in struct s2255_mode should be set whenever
991 * the image size could change via color format, video system or image
992 * size.
993 * When the restart parameter is set, we sleep for ONE frame to allow the
994 * DSP time to get the new frame
995 */
Dean Anderson5e950fa2014-02-04 18:16:24 -0300996static int s2255_set_mode(struct s2255_vc *vc,
Dean Anderson38f993a2008-06-26 23:15:51 -0300997 struct s2255_mode *mode)
998{
999 int res;
Dean Anderson38f993a2008-06-26 23:15:51 -03001000 unsigned long chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001001 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001002 int i;
Dean Anderson47d8c882014-02-05 15:43:51 -03001003 __le32 *buffer = dev->cmdbuf;
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001004
Dean Anderson47d8c882014-02-05 15:43:51 -03001005 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001006 chn_rev = G_chnmap[vc->idx];
1007 dprintk(dev, 3, "%s channel: %d\n", __func__, vc->idx);
Dean Anderson22b88d42008-08-29 15:33:19 -03001008 /* if JPEG, set the quality */
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001009 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1010 mode->color &= ~MASK_COLOR;
1011 mode->color |= COLOR_JPG;
1012 mode->color &= ~MASK_JPG_QUALITY;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001013 mode->color |= (vc->jpegqual << 8);
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001014 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001015 /* save the mode */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001016 vc->mode = *mode;
1017 vc->req_image_size = get_transfer_size(mode);
1018 dprintk(dev, 1, "%s: reqsize %ld\n", __func__, vc->req_image_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001019 /* set the mode */
1020 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001021 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001022 buffer[2] = CMD_SET_MODE;
Hans Verkuil0b84caa2013-02-26 14:14:19 -03001023 for (i = 0; i < sizeof(struct s2255_mode) / sizeof(u32); i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001024 buffer[3 + i] = cpu_to_le32(((u32 *)&vc->mode)[i]);
1025 vc->setmode_ready = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001026 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1027 if (debug)
Dean Anderson85b85482010-04-08 23:51:17 -03001028 s2255_print_cfg(dev, mode);
Dean Anderson38f993a2008-06-26 23:15:51 -03001029 /* wait at least 3 frames before continuing */
Dean Anderson14d96262008-08-25 13:58:55 -03001030 if (mode->restart) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001031 wait_event_timeout(vc->wait_setmode,
1032 (vc->setmode_ready != 0),
Dean Anderson14d96262008-08-25 13:58:55 -03001033 msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001034 if (vc->setmode_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001035 dprintk(dev, 0, "s2255: no set mode response\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001036 res = -EFAULT;
1037 }
1038 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001039 /* clear the restart flag */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001040 vc->mode.restart = 0;
1041 dprintk(dev, 1, "%s chn %d, result: %d\n", __func__, vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03001042 mutex_unlock(&dev->cmdlock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001043 return res;
1044}
1045
Dean Anderson5e950fa2014-02-04 18:16:24 -03001046static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
Dean Anderson4de39f52010-03-03 19:39:19 -03001047{
1048 int res;
Dean Anderson4de39f52010-03-03 19:39:19 -03001049 u32 chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001050 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03001051 __le32 *buffer = dev->cmdbuf;
1052
1053 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001054 chn_rev = G_chnmap[vc->idx];
1055 dprintk(dev, 4, "%s chan %d\n", __func__, vc->idx);
Dean Anderson4de39f52010-03-03 19:39:19 -03001056 /* form the get vid status command */
1057 buffer[0] = IN_DATA_TOKEN;
Dean Anderson3fa00602010-03-04 20:47:33 -03001058 buffer[1] = (__le32) cpu_to_le32(chn_rev);
Dean Anderson4de39f52010-03-03 19:39:19 -03001059 buffer[2] = CMD_STATUS;
1060 *pstatus = 0;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001061 vc->vidstatus_ready = 0;
Dean Anderson4de39f52010-03-03 19:39:19 -03001062 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001063 wait_event_timeout(vc->wait_vidstatus,
1064 (vc->vidstatus_ready != 0),
Dean Anderson4de39f52010-03-03 19:39:19 -03001065 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001066 if (vc->vidstatus_ready != 1) {
sensoray-devf5402002014-01-29 15:24:07 -03001067 dprintk(dev, 0, "s2255: no vidstatus response\n");
Dean Anderson4de39f52010-03-03 19:39:19 -03001068 res = -EFAULT;
1069 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001070 *pstatus = vc->vidstatus;
sensoray-devf5402002014-01-29 15:24:07 -03001071 dprintk(dev, 4, "%s, vid status %d\n", __func__, *pstatus);
Dean Anderson47d8c882014-02-05 15:43:51 -03001072 mutex_unlock(&dev->cmdlock);
Dean Anderson4de39f52010-03-03 19:39:19 -03001073 return res;
1074}
1075
sensoray-dev340a30c2014-02-12 17:25:45 -03001076static int start_streaming(struct vb2_queue *vq, unsigned int count)
Dean Anderson38f993a2008-06-26 23:15:51 -03001077{
sensoray-dev340a30c2014-02-12 17:25:45 -03001078 struct s2255_vc *vc = vb2_get_drv_priv(vq);
Dean Anderson38f993a2008-06-26 23:15:51 -03001079 int j;
Dean Anderson92cde472014-02-05 17:38:42 -03001080
Dean Anderson5e950fa2014-02-04 18:16:24 -03001081 vc->last_frame = -1;
1082 vc->bad_payload = 0;
1083 vc->cur_frame = 0;
1084 vc->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001085 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001086 vc->buffer.frame[j].ulState = S2255_READ_IDLE;
1087 vc->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001088 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001089 return s2255_start_acquire(vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03001090}
1091
sensoray-dev340a30c2014-02-12 17:25:45 -03001092/* abort streaming and wait for last buffer */
Hans Verkuile37559b2014-04-17 02:47:21 -03001093static void stop_streaming(struct vb2_queue *vq)
Dean Anderson38f993a2008-06-26 23:15:51 -03001094{
sensoray-dev340a30c2014-02-12 17:25:45 -03001095 struct s2255_vc *vc = vb2_get_drv_priv(vq);
1096 struct s2255_buffer *buf, *node;
1097 unsigned long flags;
1098 (void) s2255_stop_acquire(vc);
1099 spin_lock_irqsave(&vc->qlock, flags);
1100 list_for_each_entry_safe(buf, node, &vc->buf_list, list) {
1101 list_del(&buf->list);
Junghak Sung2d700712015-09-22 10:30:30 -03001102 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
sensoray-dev340a30c2014-02-12 17:25:45 -03001103 dprintk(vc->dev, 2, "[%p/%d] done\n",
Junghak Sung2d700712015-09-22 10:30:30 -03001104 buf, buf->vb.vb2_buf.index);
sensoray-dev340a30c2014-02-12 17:25:45 -03001105 }
1106 spin_unlock_irqrestore(&vc->qlock, flags);
Dean Anderson38f993a2008-06-26 23:15:51 -03001107}
1108
Hans Verkuil314527a2013-03-15 06:10:40 -03001109static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i)
Dean Anderson38f993a2008-06-26 23:15:51 -03001110{
sensoray-dev340a30c2014-02-12 17:25:45 -03001111 struct s2255_vc *vc = video_drvdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001112 struct s2255_mode mode;
sensoray-dev340a30c2014-02-12 17:25:45 -03001113 struct vb2_queue *q = &vc->vb_vidq;
Hans Verkuil469af772013-02-15 06:12:58 -03001114
sensoray-dev340a30c2014-02-12 17:25:45 -03001115 /*
1116 * Changing the standard implies a format change, which is not allowed
1117 * while buffers for use with streaming have already been allocated.
1118 */
1119 if (vb2_is_busy(q))
1120 return -EBUSY;
1121
Dean Anderson92cde472014-02-05 17:38:42 -03001122 mode = vc->mode;
Hans Verkuil314527a2013-03-15 06:10:40 -03001123 if (i & V4L2_STD_525_60) {
Dean Anderson92cde472014-02-05 17:38:42 -03001124 dprintk(vc->dev, 4, "%s 60 Hz\n", __func__);
Dean Andersone6b44bc2010-03-08 20:04:48 -03001125 /* if changing format, reset frame decimation/intervals */
Dean Andersonfe85ce92010-06-01 19:12:07 -03001126 if (mode.format != FORMAT_NTSC) {
1127 mode.restart = 1;
1128 mode.format = FORMAT_NTSC;
1129 mode.fdec = FDEC_1;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001130 vc->width = LINE_SZ_4CIFS_NTSC;
1131 vc->height = NUM_LINES_4CIFS_NTSC * 2;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001132 }
Hans Verkuil314527a2013-03-15 06:10:40 -03001133 } else if (i & V4L2_STD_625_50) {
Dean Anderson92cde472014-02-05 17:38:42 -03001134 dprintk(vc->dev, 4, "%s 50 Hz\n", __func__);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001135 if (mode.format != FORMAT_PAL) {
1136 mode.restart = 1;
1137 mode.format = FORMAT_PAL;
1138 mode.fdec = FDEC_1;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001139 vc->width = LINE_SZ_4CIFS_PAL;
1140 vc->height = NUM_LINES_4CIFS_PAL * 2;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001141 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001142 } else
1143 return -EINVAL;
Dean Anderson92cde472014-02-05 17:38:42 -03001144 vc->std = i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001145 if (mode.restart)
Dean Anderson92cde472014-02-05 17:38:42 -03001146 s2255_set_mode(vc, &mode);
sensoray-dev340a30c2014-02-12 17:25:45 -03001147 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001148}
1149
Hans Verkuil469af772013-02-15 06:12:58 -03001150static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *i)
1151{
sensoray-dev340a30c2014-02-12 17:25:45 -03001152 struct s2255_vc *vc = video_drvdata(file);
Hans Verkuil469af772013-02-15 06:12:58 -03001153
Dean Anderson92cde472014-02-05 17:38:42 -03001154 *i = vc->std;
Hans Verkuil469af772013-02-15 06:12:58 -03001155 return 0;
1156}
1157
Dean Anderson38f993a2008-06-26 23:15:51 -03001158/* Sensoray 2255 is a multiple channel capture device.
1159 It does not have a "crossbar" of inputs.
1160 We use one V4L device per channel. The user must
1161 be aware that certain combinations are not allowed.
1162 For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
1163 at once in color(you can do full fps on 4 channels with greyscale.
1164*/
1165static int vidioc_enum_input(struct file *file, void *priv,
1166 struct v4l2_input *inp)
1167{
sensoray-dev340a30c2014-02-12 17:25:45 -03001168 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson92cde472014-02-05 17:38:42 -03001169 struct s2255_dev *dev = vc->dev;
Dean Anderson4de39f52010-03-03 19:39:19 -03001170 u32 status = 0;
Dean Anderson92cde472014-02-05 17:38:42 -03001171
Dean Anderson38f993a2008-06-26 23:15:51 -03001172 if (inp->index != 0)
1173 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001174 inp->type = V4L2_INPUT_TYPE_CAMERA;
1175 inp->std = S2255_NORMS;
Dean Anderson4de39f52010-03-03 19:39:19 -03001176 inp->status = 0;
1177 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1178 int rc;
Dean Anderson92cde472014-02-05 17:38:42 -03001179 rc = s2255_cmd_status(vc, &status);
sensoray-devf5402002014-01-29 15:24:07 -03001180 dprintk(dev, 4, "s2255_cmd_status rc: %d status %x\n",
1181 rc, status);
Dean Anderson4de39f52010-03-03 19:39:19 -03001182 if (rc == 0)
1183 inp->status = (status & 0x01) ? 0
1184 : V4L2_IN_ST_NO_SIGNAL;
1185 }
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001186 switch (dev->pid) {
1187 case 0x2255:
1188 default:
Mauro Carvalho Chehabc0decac2018-09-10 08:19:14 -04001189 strscpy(inp->name, "Composite", sizeof(inp->name));
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001190 break;
1191 case 0x2257:
Mauro Carvalho Chehabc0decac2018-09-10 08:19:14 -04001192 strscpy(inp->name, (vc->idx < 2) ? "Composite" : "S-Video",
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001193 sizeof(inp->name));
1194 break;
1195 }
Dean Anderson3f8d6f72008-06-30 21:28:34 -03001196 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001197}
1198
1199static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1200{
1201 *i = 0;
1202 return 0;
1203}
1204static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1205{
1206 if (i > 0)
1207 return -EINVAL;
1208 return 0;
1209}
1210
Hans Verkuil192f1e72013-02-15 05:51:21 -03001211static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
Dean Anderson38f993a2008-06-26 23:15:51 -03001212{
Dean Anderson5e950fa2014-02-04 18:16:24 -03001213 struct s2255_vc *vc =
1214 container_of(ctrl->handler, struct s2255_vc, hdl);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001215 struct s2255_mode mode;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001216 mode = vc->mode;
Dean Anderson2e70db92010-03-05 14:29:09 -03001217 /* update the mode to the corresponding value */
1218 switch (ctrl->id) {
1219 case V4L2_CID_BRIGHTNESS:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001220 mode.bright = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001221 break;
1222 case V4L2_CID_CONTRAST:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001223 mode.contrast = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001224 break;
1225 case V4L2_CID_HUE:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001226 mode.hue = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001227 break;
1228 case V4L2_CID_SATURATION:
Hans Verkuil192f1e72013-02-15 05:51:21 -03001229 mode.saturation = ctrl->val;
Dean Anderson2e70db92010-03-05 14:29:09 -03001230 break;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001231 case V4L2_CID_S2255_COLORFILTER:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001232 mode.color &= ~MASK_INPUT_TYPE;
Hans Verkuil192f1e72013-02-15 05:51:21 -03001233 mode.color |= !ctrl->val << 16;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03001234 break;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001235 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001236 vc->jpegqual = ctrl->val;
Hans Verkuil7041dec2013-02-15 05:53:45 -03001237 return 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001238 default:
1239 return -EINVAL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001240 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001241 mode.restart = 0;
Dean Anderson2e70db92010-03-05 14:29:09 -03001242 /* set mode here. Note: stream does not need restarted.
1243 some V4L programs restart stream unnecessarily
1244 after a s_crtl.
1245 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001246 s2255_set_mode(vc, &mode);
Dean Anderson2e70db92010-03-05 14:29:09 -03001247 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001248}
1249
Dean Anderson22b88d42008-08-29 15:33:19 -03001250static int vidioc_g_jpegcomp(struct file *file, void *priv,
1251 struct v4l2_jpegcompression *jc)
1252{
sensoray-dev340a30c2014-02-12 17:25:45 -03001253 struct s2255_vc *vc = video_drvdata(file);
Hans Verkuil7041dec2013-02-15 05:53:45 -03001254
1255 memset(jc, 0, sizeof(*jc));
Dean Anderson5e950fa2014-02-04 18:16:24 -03001256 jc->quality = vc->jpegqual;
Dean Anderson92cde472014-02-05 17:38:42 -03001257 dprintk(vc->dev, 2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001258 return 0;
1259}
1260
1261static int vidioc_s_jpegcomp(struct file *file, void *priv,
Hans Verkuild88aab52012-09-17 05:05:25 -03001262 const struct v4l2_jpegcompression *jc)
Dean Anderson22b88d42008-08-29 15:33:19 -03001263{
sensoray-dev340a30c2014-02-12 17:25:45 -03001264 struct s2255_vc *vc = video_drvdata(file);
1265
Dean Anderson22b88d42008-08-29 15:33:19 -03001266 if (jc->quality < 0 || jc->quality > 100)
1267 return -EINVAL;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001268 v4l2_ctrl_s_ctrl(vc->jpegqual_ctrl, jc->quality);
Dean Anderson92cde472014-02-05 17:38:42 -03001269 dprintk(vc->dev, 2, "%s: quality %d\n", __func__, jc->quality);
Dean Anderson22b88d42008-08-29 15:33:19 -03001270 return 0;
1271}
Dean Anderson7d853532009-05-15 14:32:04 -03001272
1273static int vidioc_g_parm(struct file *file, void *priv,
1274 struct v4l2_streamparm *sp)
1275{
Dean Andersone6b44bc2010-03-08 20:04:48 -03001276 __u32 def_num, def_dem;
sensoray-dev340a30c2014-02-12 17:25:45 -03001277 struct s2255_vc *vc = video_drvdata(file);
1278
Dean Anderson7d853532009-05-15 14:32:04 -03001279 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1280 return -EINVAL;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001281 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001282 sp->parm.capture.capturemode = vc->cap_parm.capturemode;
sensoray-dev340a30c2014-02-12 17:25:45 -03001283 sp->parm.capture.readbuffers = S2255_MIN_BUFS;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001284 def_num = (vc->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1285 def_dem = (vc->mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001286 sp->parm.capture.timeperframe.denominator = def_dem;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001287 switch (vc->mode.fdec) {
Dean Andersone6b44bc2010-03-08 20:04:48 -03001288 default:
1289 case FDEC_1:
1290 sp->parm.capture.timeperframe.numerator = def_num;
1291 break;
1292 case FDEC_2:
1293 sp->parm.capture.timeperframe.numerator = def_num * 2;
1294 break;
1295 case FDEC_3:
1296 sp->parm.capture.timeperframe.numerator = def_num * 3;
1297 break;
1298 case FDEC_5:
1299 sp->parm.capture.timeperframe.numerator = def_num * 5;
1300 break;
1301 }
Dean Anderson92cde472014-02-05 17:38:42 -03001302 dprintk(vc->dev, 4, "%s capture mode, %d timeperframe %d/%d\n",
sensoray-devf5402002014-01-29 15:24:07 -03001303 __func__,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001304 sp->parm.capture.capturemode,
1305 sp->parm.capture.timeperframe.numerator,
1306 sp->parm.capture.timeperframe.denominator);
Dean Anderson7d853532009-05-15 14:32:04 -03001307 return 0;
1308}
1309
1310static int vidioc_s_parm(struct file *file, void *priv,
1311 struct v4l2_streamparm *sp)
1312{
sensoray-dev340a30c2014-02-12 17:25:45 -03001313 struct s2255_vc *vc = video_drvdata(file);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001314 struct s2255_mode mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001315 int fdec = FDEC_1;
1316 __u32 def_num, def_dem;
Dean Anderson7d853532009-05-15 14:32:04 -03001317 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1318 return -EINVAL;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001319 mode = vc->mode;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001320 /* high quality capture mode requires a stream restart */
sensoray-dev340a30c2014-02-12 17:25:45 -03001321 if ((vc->cap_parm.capturemode != sp->parm.capture.capturemode)
1322 && vb2_is_streaming(&vc->vb_vidq))
Dean Andersone6b44bc2010-03-08 20:04:48 -03001323 return -EBUSY;
Dean Andersonfe85ce92010-06-01 19:12:07 -03001324 def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
1325 def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001326 if (def_dem != sp->parm.capture.timeperframe.denominator)
1327 sp->parm.capture.timeperframe.numerator = def_num;
1328 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1329 sp->parm.capture.timeperframe.numerator = def_num;
1330 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1331 sp->parm.capture.timeperframe.numerator = def_num * 2;
1332 fdec = FDEC_2;
1333 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1334 sp->parm.capture.timeperframe.numerator = def_num * 3;
1335 fdec = FDEC_3;
1336 } else {
1337 sp->parm.capture.timeperframe.numerator = def_num * 5;
1338 fdec = FDEC_5;
1339 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001340 mode.fdec = fdec;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001341 sp->parm.capture.timeperframe.denominator = def_dem;
sensoray-dev340a30c2014-02-12 17:25:45 -03001342 sp->parm.capture.readbuffers = S2255_MIN_BUFS;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001343 s2255_set_mode(vc, &mode);
Dean Anderson92cde472014-02-05 17:38:42 -03001344 dprintk(vc->dev, 4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
Dean Andersone6b44bc2010-03-08 20:04:48 -03001345 __func__,
1346 sp->parm.capture.capturemode,
1347 sp->parm.capture.timeperframe.numerator,
1348 sp->parm.capture.timeperframe.denominator, fdec);
Dean Anderson7d853532009-05-15 14:32:04 -03001349 return 0;
1350}
Dean Andersone6b44bc2010-03-08 20:04:48 -03001351
Hans Verkuil05e5d442013-02-15 06:09:18 -03001352#define NUM_SIZE_ENUMS 3
1353static const struct v4l2_frmsize_discrete ntsc_sizes[] = {
1354 { 640, 480 },
1355 { 640, 240 },
1356 { 320, 240 },
1357};
1358static const struct v4l2_frmsize_discrete pal_sizes[] = {
1359 { 704, 576 },
1360 { 704, 288 },
1361 { 352, 288 },
1362};
1363
1364static int vidioc_enum_framesizes(struct file *file, void *priv,
1365 struct v4l2_frmsizeenum *fe)
1366{
sensoray-dev340a30c2014-02-12 17:25:45 -03001367 struct s2255_vc *vc = video_drvdata(file);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001368 int is_ntsc = vc->std & V4L2_STD_525_60;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001369 const struct s2255_fmt *fmt;
1370
1371 if (fe->index >= NUM_SIZE_ENUMS)
1372 return -EINVAL;
1373
1374 fmt = format_by_fourcc(fe->pixel_format);
1375 if (fmt == NULL)
1376 return -EINVAL;
1377 fe->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1378 fe->discrete = is_ntsc ? ntsc_sizes[fe->index] : pal_sizes[fe->index];
1379 return 0;
1380}
1381
Dean Andersone6b44bc2010-03-08 20:04:48 -03001382static int vidioc_enum_frameintervals(struct file *file, void *priv,
1383 struct v4l2_frmivalenum *fe)
1384{
sensoray-dev340a30c2014-02-12 17:25:45 -03001385 struct s2255_vc *vc = video_drvdata(file);
Hans Verkuil05e5d442013-02-15 06:09:18 -03001386 const struct s2255_fmt *fmt;
1387 const struct v4l2_frmsize_discrete *sizes;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001388 int is_ntsc = vc->std & V4L2_STD_525_60;
Dean Andersone6b44bc2010-03-08 20:04:48 -03001389#define NUM_FRAME_ENUMS 4
1390 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
Hans Verkuil05e5d442013-02-15 06:09:18 -03001391 int i;
1392
Mauro Carvalho Chehab199ab8f2012-10-27 16:29:34 -03001393 if (fe->index >= NUM_FRAME_ENUMS)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001394 return -EINVAL;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001395
1396 fmt = format_by_fourcc(fe->pixel_format);
1397 if (fmt == NULL)
Dean Andersone6b44bc2010-03-08 20:04:48 -03001398 return -EINVAL;
Hans Verkuil05e5d442013-02-15 06:09:18 -03001399
1400 sizes = is_ntsc ? ntsc_sizes : pal_sizes;
1401 for (i = 0; i < NUM_SIZE_ENUMS; i++, sizes++)
1402 if (fe->width == sizes->width &&
1403 fe->height == sizes->height)
1404 break;
1405 if (i == NUM_SIZE_ENUMS)
1406 return -EINVAL;
1407
Dean Andersone6b44bc2010-03-08 20:04:48 -03001408 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1409 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1410 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
Dean Anderson92cde472014-02-05 17:38:42 -03001411 dprintk(vc->dev, 4, "%s discrete %d/%d\n", __func__,
sensoray-devf5402002014-01-29 15:24:07 -03001412 fe->discrete.numerator,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001413 fe->discrete.denominator);
1414 return 0;
1415}
1416
sensoray-dev340a30c2014-02-12 17:25:45 -03001417static int s2255_open(struct file *file)
Dean Anderson38f993a2008-06-26 23:15:51 -03001418{
Dean Anderson5e950fa2014-02-04 18:16:24 -03001419 struct s2255_vc *vc = video_drvdata(file);
sensoray-dev340a30c2014-02-12 17:25:45 -03001420 struct s2255_dev *dev = vc->dev;
Dean Anderson14d96262008-08-25 13:58:55 -03001421 int state;
sensoray-dev340a30c2014-02-12 17:25:45 -03001422 int rc = 0;
1423
1424 rc = v4l2_fh_open(file);
1425 if (rc != 0)
1426 return rc;
1427
1428 dprintk(dev, 1, "s2255: %s\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001429 state = atomic_read(&dev->fw_data->fw_state);
1430 switch (state) {
1431 case S2255_FW_DISCONNECTING:
Dean Andersonff7e22d2010-04-08 23:38:07 -03001432 return -ENODEV;
Dean Anderson14d96262008-08-25 13:58:55 -03001433 case S2255_FW_FAILED:
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03001434 s2255_dev_err(&dev->udev->dev,
1435 "firmware load failed. retrying.\n");
Dean Ae2a06702017-11-03 16:11:03 -04001436 s2255_fwload_start(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001437 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001438 ((atomic_read(&dev->fw_data->fw_state)
1439 == S2255_FW_SUCCESS) ||
1440 (atomic_read(&dev->fw_data->fw_state)
1441 == S2255_FW_DISCONNECTING)),
Dean Anderson38f993a2008-06-26 23:15:51 -03001442 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001443 /* state may have changed, re-read */
1444 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001445 break;
1446 case S2255_FW_NOTLOADED:
1447 case S2255_FW_LOADED_DSPWAIT:
Dean Anderson38f993a2008-06-26 23:15:51 -03001448 /* give S2255_LOAD_TIMEOUT time for firmware to load in case
1449 driver loaded and then device immediately opened */
sensoray-devf5402002014-01-29 15:24:07 -03001450 pr_info("%s waiting for firmware load\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001451 wait_event_timeout(dev->fw_data->wait_fw,
Dean Anderson14d96262008-08-25 13:58:55 -03001452 ((atomic_read(&dev->fw_data->fw_state)
1453 == S2255_FW_SUCCESS) ||
1454 (atomic_read(&dev->fw_data->fw_state)
1455 == S2255_FW_DISCONNECTING)),
Dean Andersoneb78dee2010-04-12 15:05:37 -03001456 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
Dean Andersonff7e22d2010-04-08 23:38:07 -03001457 /* state may have changed, re-read */
1458 state = atomic_read(&dev->fw_data->fw_state);
Dean Anderson14d96262008-08-25 13:58:55 -03001459 break;
1460 case S2255_FW_SUCCESS:
1461 default:
1462 break;
1463 }
Dean Andersonff7e22d2010-04-08 23:38:07 -03001464 /* state may have changed in above switch statement */
1465 switch (state) {
1466 case S2255_FW_SUCCESS:
1467 break;
1468 case S2255_FW_FAILED:
sensoray-devf5402002014-01-29 15:24:07 -03001469 pr_info("2255 firmware load failed.\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03001470 return -ENODEV;
1471 case S2255_FW_DISCONNECTING:
sensoray-devf5402002014-01-29 15:24:07 -03001472 pr_info("%s: disconnecting\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001473 return -ENODEV;
1474 case S2255_FW_LOADED_DSPWAIT:
1475 case S2255_FW_NOTLOADED:
sensoray-devf5402002014-01-29 15:24:07 -03001476 pr_info("%s: firmware not loaded, please retry\n",
1477 __func__);
Dean Andersoneb78dee2010-04-12 15:05:37 -03001478 /*
1479 * Timeout on firmware load means device unusable.
1480 * Set firmware failure state.
1481 * On next s2255_open the firmware will be reloaded.
1482 */
1483 atomic_set(&dev->fw_data->fw_state,
1484 S2255_FW_FAILED);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001485 return -EAGAIN;
1486 default:
sensoray-devf5402002014-01-29 15:24:07 -03001487 pr_info("%s: unknown state\n", __func__);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001488 return -EFAULT;
Dean Anderson38f993a2008-06-26 23:15:51 -03001489 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001490 if (!vc->configured) {
Dean Andersonfe85ce92010-06-01 19:12:07 -03001491 /* configure channel to default state */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001492 vc->fmt = &formats[0];
1493 s2255_set_mode(vc, &vc->mode);
1494 vc->configured = 1;
Dean Anderson14d96262008-08-25 13:58:55 -03001495 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001496 return 0;
1497}
1498
Dean Andersond62e85a2010-04-09 19:54:26 -03001499static void s2255_destroy(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03001500{
sensoray-devf5402002014-01-29 15:24:07 -03001501 dprintk(dev, 1, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03001502 /* board shutdown stops the read pipe if it is running */
1503 s2255_board_shutdown(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001504 /* make sure firmware still not trying to load */
Kirill Tkhai9f6be2b2014-04-17 17:47:04 -03001505 del_timer_sync(&dev->timer); /* only started in .probe and .open */
Dean Anderson38f993a2008-06-26 23:15:51 -03001506 if (dev->fw_data->fw_urb) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001507 usb_kill_urb(dev->fw_data->fw_urb);
1508 usb_free_urb(dev->fw_data->fw_urb);
1509 dev->fw_data->fw_urb = NULL;
1510 }
Jesper Juhl3fc82fa2012-04-09 16:50:04 -03001511 release_firmware(dev->fw_data->fw);
Dean Andersonf78d92c2008-07-22 14:43:27 -03001512 kfree(dev->fw_data->pfw_data);
1513 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001514 /* reset the DSP so firmware can be reloaded next time */
1515 s2255_reset_dsppower(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001516 mutex_destroy(&dev->lock);
Dean Anderson38f993a2008-06-26 23:15:51 -03001517 usb_put_dev(dev->udev);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001518 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03001519 kfree(dev->cmdbuf);
Dean Andersonb7732a32009-03-30 11:59:56 -03001520 kfree(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03001521}
1522
Hans Verkuilbec43662008-12-30 06:58:20 -03001523static const struct v4l2_file_operations s2255_fops_v4l = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001524 .owner = THIS_MODULE,
1525 .open = s2255_open,
sensoray-dev340a30c2014-02-12 17:25:45 -03001526 .release = vb2_fop_release,
1527 .poll = vb2_fop_poll,
Pete Eberleina19a5cd2010-12-20 19:18:59 -03001528 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
sensoray-dev340a30c2014-02-12 17:25:45 -03001529 .mmap = vb2_fop_mmap,
1530 .read = vb2_fop_read,
Dean Anderson38f993a2008-06-26 23:15:51 -03001531};
1532
Hans Verkuila3998102008-07-21 02:57:38 -03001533static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
Dean Anderson38f993a2008-06-26 23:15:51 -03001534 .vidioc_querycap = vidioc_querycap,
1535 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1536 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1537 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1538 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
sensoray-dev340a30c2014-02-12 17:25:45 -03001539 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1540 .vidioc_querybuf = vb2_ioctl_querybuf,
1541 .vidioc_qbuf = vb2_ioctl_qbuf,
1542 .vidioc_dqbuf = vb2_ioctl_dqbuf,
Dean Anderson38f993a2008-06-26 23:15:51 -03001543 .vidioc_s_std = vidioc_s_std,
Hans Verkuil469af772013-02-15 06:12:58 -03001544 .vidioc_g_std = vidioc_g_std,
Dean Anderson38f993a2008-06-26 23:15:51 -03001545 .vidioc_enum_input = vidioc_enum_input,
1546 .vidioc_g_input = vidioc_g_input,
1547 .vidioc_s_input = vidioc_s_input,
sensoray-dev340a30c2014-02-12 17:25:45 -03001548 .vidioc_streamon = vb2_ioctl_streamon,
1549 .vidioc_streamoff = vb2_ioctl_streamoff,
Dean Anderson22b88d42008-08-29 15:33:19 -03001550 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1551 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
Dean Anderson7d853532009-05-15 14:32:04 -03001552 .vidioc_s_parm = vidioc_s_parm,
1553 .vidioc_g_parm = vidioc_g_parm,
Hans Verkuil05e5d442013-02-15 06:09:18 -03001554 .vidioc_enum_framesizes = vidioc_enum_framesizes,
Dean Andersone6b44bc2010-03-08 20:04:48 -03001555 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
Hans Verkuil44d06d82013-02-15 05:59:00 -03001556 .vidioc_log_status = v4l2_ctrl_log_status,
1557 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1558 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Hans Verkuila3998102008-07-21 02:57:38 -03001559};
1560
Dean Andersonff7e22d2010-04-08 23:38:07 -03001561static void s2255_video_device_release(struct video_device *vdev)
1562{
Dean Andersonfe85ce92010-06-01 19:12:07 -03001563 struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001564 struct s2255_vc *vc =
1565 container_of(vdev, struct s2255_vc, vdev);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001566
sensoray-devf5402002014-01-29 15:24:07 -03001567 dprintk(dev, 4, "%s, chnls: %d\n", __func__,
Dean Andersonfe85ce92010-06-01 19:12:07 -03001568 atomic_read(&dev->num_channels));
Hans Verkuil192f1e72013-02-15 05:51:21 -03001569
Dean Anderson5e950fa2014-02-04 18:16:24 -03001570 v4l2_ctrl_handler_free(&vc->hdl);
sensoray-devf5402002014-01-29 15:24:07 -03001571
Dean Andersonfe85ce92010-06-01 19:12:07 -03001572 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03001573 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03001574 return;
1575}
1576
Bhumika Goyal86844942017-08-26 09:11:30 -04001577static const struct video_device template = {
Hans Verkuila3998102008-07-21 02:57:38 -03001578 .name = "s2255v",
Hans Verkuila3998102008-07-21 02:57:38 -03001579 .fops = &s2255_fops_v4l,
1580 .ioctl_ops = &s2255_ioctl_ops,
Dean Andersonff7e22d2010-04-08 23:38:07 -03001581 .release = s2255_video_device_release,
Dean Anderson38f993a2008-06-26 23:15:51 -03001582 .tvnorms = S2255_NORMS,
Dean Anderson38f993a2008-06-26 23:15:51 -03001583};
1584
Hans Verkuil192f1e72013-02-15 05:51:21 -03001585static const struct v4l2_ctrl_ops s2255_ctrl_ops = {
1586 .s_ctrl = s2255_s_ctrl,
1587};
1588
1589static const struct v4l2_ctrl_config color_filter_ctrl = {
1590 .ops = &s2255_ctrl_ops,
1591 .name = "Color Filter",
1592 .id = V4L2_CID_S2255_COLORFILTER,
1593 .type = V4L2_CTRL_TYPE_BOOLEAN,
1594 .max = 1,
1595 .step = 1,
1596 .def = 1,
1597};
1598
Dean Anderson38f993a2008-06-26 23:15:51 -03001599static int s2255_probe_v4l(struct s2255_dev *dev)
1600{
1601 int ret;
1602 int i;
1603 int cur_nr = video_nr;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001604 struct s2255_vc *vc;
sensoray-dev340a30c2014-02-12 17:25:45 -03001605 struct vb2_queue *q;
1606
Dean Anderson65c6edb2010-04-20 17:21:32 -03001607 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1608 if (ret)
1609 return ret;
Dean Anderson38f993a2008-06-26 23:15:51 -03001610 /* initialize all video 4 linux */
Dean Anderson38f993a2008-06-26 23:15:51 -03001611 /* register 4 video devices */
1612 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001613 vc = &dev->vc[i];
1614 INIT_LIST_HEAD(&vc->buf_list);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001615
Dean Anderson5e950fa2014-02-04 18:16:24 -03001616 v4l2_ctrl_handler_init(&vc->hdl, 6);
1617 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001618 V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001619 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001620 V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001621 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001622 V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001623 v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
Hans Verkuil192f1e72013-02-15 05:51:21 -03001624 V4L2_CID_HUE, 0, 255, 1, DEF_HUE);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001625 vc->jpegqual_ctrl = v4l2_ctrl_new_std(&vc->hdl,
Hans Verkuil7041dec2013-02-15 05:53:45 -03001626 &s2255_ctrl_ops,
1627 V4L2_CID_JPEG_COMPRESSION_QUALITY,
1628 0, 100, 1, S2255_DEF_JPEG_QUAL);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001629 if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER &&
Dean Anderson5e950fa2014-02-04 18:16:24 -03001630 (dev->pid != 0x2257 || vc->idx <= 1))
1631 v4l2_ctrl_new_custom(&vc->hdl, &color_filter_ctrl,
sensoray-devf5402002014-01-29 15:24:07 -03001632 NULL);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001633 if (vc->hdl.error) {
1634 ret = vc->hdl.error;
1635 v4l2_ctrl_handler_free(&vc->hdl);
Hans Verkuil192f1e72013-02-15 05:51:21 -03001636 dev_err(&dev->udev->dev, "couldn't register control\n");
1637 break;
1638 }
sensoray-dev340a30c2014-02-12 17:25:45 -03001639 q = &vc->vb_vidq;
1640 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1641 q->io_modes = VB2_MMAP | VB2_READ | VB2_USERPTR;
1642 q->drv_priv = vc;
1643 q->lock = &vc->vb_lock;
1644 q->buf_struct_size = sizeof(struct s2255_buffer);
1645 q->mem_ops = &vb2_vmalloc_memops;
1646 q->ops = &s2255_video_qops;
Sakari Ailusade48682014-02-25 19:12:19 -03001647 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
sensoray-dev340a30c2014-02-12 17:25:45 -03001648 ret = vb2_queue_init(q);
1649 if (ret != 0) {
1650 dev_err(&dev->udev->dev,
1651 "%s vb2_queue_init 0x%x\n", __func__, ret);
1652 break;
1653 }
1654 /* register video devices */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001655 vc->vdev = template;
sensoray-dev340a30c2014-02-12 17:25:45 -03001656 vc->vdev.queue = q;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001657 vc->vdev.ctrl_handler = &vc->hdl;
1658 vc->vdev.lock = &dev->lock;
1659 vc->vdev.v4l2_dev = &dev->v4l2_dev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001660 video_set_drvdata(&vc->vdev, vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03001661 if (video_nr == -1)
Dean Anderson5e950fa2014-02-04 18:16:24 -03001662 ret = video_register_device(&vc->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001663 VFL_TYPE_GRABBER,
1664 video_nr);
1665 else
Dean Anderson5e950fa2014-02-04 18:16:24 -03001666 ret = video_register_device(&vc->vdev,
Dean Anderson38f993a2008-06-26 23:15:51 -03001667 VFL_TYPE_GRABBER,
1668 cur_nr + i);
Dean Andersonfe85ce92010-06-01 19:12:07 -03001669
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001670 if (ret) {
Dean Anderson38f993a2008-06-26 23:15:51 -03001671 dev_err(&dev->udev->dev,
1672 "failed to register video device!\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001673 break;
Dean Anderson38f993a2008-06-26 23:15:51 -03001674 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001675 atomic_inc(&dev->num_channels);
Dean Anderson65c6edb2010-04-20 17:21:32 -03001676 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
Dean Anderson5e950fa2014-02-04 18:16:24 -03001677 video_device_node_name(&vc->vdev));
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001678
Dean Anderson38f993a2008-06-26 23:15:51 -03001679 }
sensoray-devf5402002014-01-29 15:24:07 -03001680 pr_info("Sensoray 2255 V4L driver Revision: %s\n",
1681 S2255_VERSION);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001682 /* if no channels registered, return error and probe will fail*/
Dean Andersonfe85ce92010-06-01 19:12:07 -03001683 if (atomic_read(&dev->num_channels) == 0) {
Dean Anderson65c6edb2010-04-20 17:21:32 -03001684 v4l2_device_unregister(&dev->v4l2_dev);
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001685 return ret;
Dean Anderson65c6edb2010-04-20 17:21:32 -03001686 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03001687 if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
sensoray-devf5402002014-01-29 15:24:07 -03001688 pr_warn("s2255: Not all channels available.\n");
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03001689 return 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001690}
1691
Dean Anderson38f993a2008-06-26 23:15:51 -03001692/* this function moves the usb stream read pipe data
1693 * into the system buffers.
1694 * returns 0 on success, EAGAIN if more data to process( call this
1695 * function again).
1696 *
1697 * Received frame structure:
Dean Anderson14d96262008-08-25 13:58:55 -03001698 * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
Dean Anderson38f993a2008-06-26 23:15:51 -03001699 * bytes 4-7: channel: 0-3
1700 * bytes 8-11: payload size: size of the frame
1701 * bytes 12-payloadsize+12: frame data
1702 */
1703static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1704{
Dean Anderson38f993a2008-06-26 23:15:51 -03001705 char *pdest;
1706 u32 offset = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001707 int bframe = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001708 char *psrc;
1709 unsigned long copy_size;
1710 unsigned long size;
1711 s32 idx = -1;
1712 struct s2255_framei *frm;
1713 unsigned char *pdata;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001714 struct s2255_vc *vc;
sensoray-devf5402002014-01-29 15:24:07 -03001715 dprintk(dev, 100, "buffer to user\n");
Dean Anderson5e950fa2014-02-04 18:16:24 -03001716 vc = &dev->vc[dev->cc];
1717 idx = vc->cur_frame;
1718 frm = &vc->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001719 if (frm->ulState == S2255_READ_IDLE) {
1720 int jj;
1721 unsigned int cc;
Dean Anderson3fa00602010-03-04 20:47:33 -03001722 __le32 *pdword; /*data from dsp is little endian */
Dean Anderson14d96262008-08-25 13:58:55 -03001723 int payload;
1724 /* search for marker codes */
1725 pdata = (unsigned char *)pipe_info->transfer_buffer;
Dean Anderson3fa00602010-03-04 20:47:33 -03001726 pdword = (__le32 *)pdata;
Dean Anderson14d96262008-08-25 13:58:55 -03001727 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
Dean Anderson3fa00602010-03-04 20:47:33 -03001728 switch (*pdword) {
Dean Anderson14d96262008-08-25 13:58:55 -03001729 case S2255_MARKER_FRAME:
sensoray-devf5402002014-01-29 15:24:07 -03001730 dprintk(dev, 4, "marker @ offset: %d [%x %x]\n",
1731 jj, pdata[0], pdata[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001732 offset = jj + PREFIX_SIZE;
1733 bframe = 1;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001734 cc = le32_to_cpu(pdword[1]);
Dean Anderson14d96262008-08-25 13:58:55 -03001735 if (cc >= MAX_CHANNELS) {
sensoray-devf5402002014-01-29 15:24:07 -03001736 dprintk(dev, 0,
1737 "bad channel\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001738 return -EINVAL;
1739 }
1740 /* reverse it */
1741 dev->cc = G_chnmap[cc];
Dean Anderson5e950fa2014-02-04 18:16:24 -03001742 vc = &dev->vc[dev->cc];
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001743 payload = le32_to_cpu(pdword[3]);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001744 if (payload > vc->req_image_size) {
1745 vc->bad_payload++;
Dean Anderson14d96262008-08-25 13:58:55 -03001746 /* discard the bad frame */
1747 return -EINVAL;
1748 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001749 vc->pkt_size = payload;
1750 vc->jpg_size = le32_to_cpu(pdword[4]);
Dean Anderson14d96262008-08-25 13:58:55 -03001751 break;
1752 case S2255_MARKER_RESPONSE:
Dean Andersonfe85ce92010-06-01 19:12:07 -03001753
Dean Anderson14d96262008-08-25 13:58:55 -03001754 pdata += DEF_USB_BLOCK;
1755 jj += DEF_USB_BLOCK;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001756 if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001757 break;
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001758 cc = G_chnmap[le32_to_cpu(pdword[1])];
Roel Kluinf14a2972009-10-23 07:59:42 -03001759 if (cc >= MAX_CHANNELS)
Dean Anderson14d96262008-08-25 13:58:55 -03001760 break;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001761 vc = &dev->vc[cc];
Dean Anderson14d96262008-08-25 13:58:55 -03001762 switch (pdword[2]) {
Dean Andersonabce21f2009-04-23 16:04:41 -03001763 case S2255_RESPONSE_SETMODE:
Dean Anderson14d96262008-08-25 13:58:55 -03001764 /* check if channel valid */
1765 /* set mode ready */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001766 vc->setmode_ready = 1;
1767 wake_up(&vc->wait_setmode);
sensoray-devf5402002014-01-29 15:24:07 -03001768 dprintk(dev, 5, "setmode rdy %d\n", cc);
Dean Anderson14d96262008-08-25 13:58:55 -03001769 break;
Dean Andersonabce21f2009-04-23 16:04:41 -03001770 case S2255_RESPONSE_FW:
Dean Anderson14d96262008-08-25 13:58:55 -03001771 dev->chn_ready |= (1 << cc);
1772 if ((dev->chn_ready & 0x0f) != 0x0f)
1773 break;
1774 /* all channels ready */
sensoray-devf5402002014-01-29 15:24:07 -03001775 pr_info("s2255: fw loaded\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001776 atomic_set(&dev->fw_data->fw_state,
1777 S2255_FW_SUCCESS);
1778 wake_up(&dev->fw_data->wait_fw);
1779 break;
Dean Anderson4de39f52010-03-03 19:39:19 -03001780 case S2255_RESPONSE_STATUS:
Dean Anderson5e950fa2014-02-04 18:16:24 -03001781 vc->vidstatus = le32_to_cpu(pdword[3]);
1782 vc->vidstatus_ready = 1;
1783 wake_up(&vc->wait_vidstatus);
sensoray-devf5402002014-01-29 15:24:07 -03001784 dprintk(dev, 5, "vstat %x chan %d\n",
Dan Carpenter3b2a6302012-02-17 02:44:10 -03001785 le32_to_cpu(pdword[3]), cc);
Dean Anderson4de39f52010-03-03 19:39:19 -03001786 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001787 default:
sensoray-devf5402002014-01-29 15:24:07 -03001788 pr_info("s2255 unknown resp\n");
Dean Anderson14d96262008-08-25 13:58:55 -03001789 }
Mauro Carvalho Chehabec33fbd52017-05-19 09:05:19 -03001790 pdata++;
1791 break;
Dean Anderson14d96262008-08-25 13:58:55 -03001792 default:
1793 pdata++;
1794 break;
1795 }
1796 if (bframe)
1797 break;
1798 } /* for */
1799 if (!bframe)
1800 return -EINVAL;
1801 }
Dean Anderson5e950fa2014-02-04 18:16:24 -03001802 vc = &dev->vc[dev->cc];
1803 idx = vc->cur_frame;
1804 frm = &vc->buffer.frame[idx];
Dean Anderson14d96262008-08-25 13:58:55 -03001805 /* search done. now find out if should be acquiring on this channel */
sensoray-dev340a30c2014-02-12 17:25:45 -03001806 if (!vb2_is_streaming(&vc->vb_vidq)) {
Dean Anderson14d96262008-08-25 13:58:55 -03001807 /* we found a frame, but this channel is turned off */
1808 frm->ulState = S2255_READ_IDLE;
1809 return -EINVAL;
1810 }
1811
1812 if (frm->ulState == S2255_READ_IDLE) {
1813 frm->ulState = S2255_READ_FRAME;
Dean Anderson38f993a2008-06-26 23:15:51 -03001814 frm->cur_size = 0;
1815 }
1816
Dean Anderson14d96262008-08-25 13:58:55 -03001817 /* skip the marker 512 bytes (and offset if out of sync) */
1818 psrc = (u8 *)pipe_info->transfer_buffer + offset;
1819
Dean Anderson38f993a2008-06-26 23:15:51 -03001820
1821 if (frm->lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03001822 dprintk(dev, 1, "s2255 frame buffer == NULL.%p %p %d %d",
Dean Anderson38f993a2008-06-26 23:15:51 -03001823 frm, dev, dev->cc, idx);
1824 return -ENOMEM;
1825 }
1826
1827 pdest = frm->lpvbits + frm->cur_size;
1828
Dean Anderson14d96262008-08-25 13:58:55 -03001829 copy_size = (pipe_info->cur_transfer_size - offset);
Dean Anderson38f993a2008-06-26 23:15:51 -03001830
Dean Anderson5e950fa2014-02-04 18:16:24 -03001831 size = vc->pkt_size - PREFIX_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001832
Dean Anderson14d96262008-08-25 13:58:55 -03001833 /* sanity check on pdest */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001834 if ((copy_size + frm->cur_size) < vc->req_image_size)
Dean Anderson14d96262008-08-25 13:58:55 -03001835 memcpy(pdest, psrc, copy_size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001836
Dean Anderson38f993a2008-06-26 23:15:51 -03001837 frm->cur_size += copy_size;
sensoray-devf5402002014-01-29 15:24:07 -03001838 dprintk(dev, 4, "cur_size: %lu, size: %lu\n", frm->cur_size, size);
Dean Anderson38f993a2008-06-26 23:15:51 -03001839
Dean Anderson14d96262008-08-25 13:58:55 -03001840 if (frm->cur_size >= size) {
sensoray-devf5402002014-01-29 15:24:07 -03001841 dprintk(dev, 2, "******[%d]Buffer[%d]full*******\n",
Dean Andersonfe85ce92010-06-01 19:12:07 -03001842 dev->cc, idx);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001843 vc->last_frame = vc->cur_frame;
1844 vc->cur_frame++;
Dean Anderson38f993a2008-06-26 23:15:51 -03001845 /* end of system frame ring buffer, start at zero */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001846 if ((vc->cur_frame == SYS_FRAMES) ||
1847 (vc->cur_frame == vc->buffer.dwFrames))
1848 vc->cur_frame = 0;
Dean Anderson14d96262008-08-25 13:58:55 -03001849 /* frame ready */
sensoray-dev340a30c2014-02-12 17:25:45 -03001850 if (vb2_is_streaming(&vc->vb_vidq))
Dean Anderson5e950fa2014-02-04 18:16:24 -03001851 s2255_got_frame(vc, vc->jpg_size);
1852 vc->frame_count++;
Dean Anderson14d96262008-08-25 13:58:55 -03001853 frm->ulState = S2255_READ_IDLE;
1854 frm->cur_size = 0;
1855
Dean Anderson38f993a2008-06-26 23:15:51 -03001856 }
1857 /* done successfully */
1858 return 0;
1859}
1860
1861static void s2255_read_video_callback(struct s2255_dev *dev,
1862 struct s2255_pipeinfo *pipe_info)
1863{
1864 int res;
sensoray-devf5402002014-01-29 15:24:07 -03001865 dprintk(dev, 50, "callback read video\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001866
1867 if (dev->cc >= MAX_CHANNELS) {
1868 dev->cc = 0;
1869 dev_err(&dev->udev->dev, "invalid channel\n");
1870 return;
1871 }
1872 /* otherwise copy to the system buffers */
1873 res = save_frame(dev, pipe_info);
Dean Anderson14d96262008-08-25 13:58:55 -03001874 if (res != 0)
sensoray-devf5402002014-01-29 15:24:07 -03001875 dprintk(dev, 4, "s2255: read callback failed\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001876
sensoray-devf5402002014-01-29 15:24:07 -03001877 dprintk(dev, 50, "callback read video done\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03001878 return;
1879}
1880
1881static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
1882 u16 Index, u16 Value, void *TransferBuffer,
1883 s32 TransferBufferLength, int bOut)
1884{
1885 int r;
Mauro Carvalho Chehabdb65c492016-10-10 11:11:13 -03001886 unsigned char *buf;
1887
1888 buf = kmalloc(TransferBufferLength, GFP_KERNEL);
1889 if (!buf)
1890 return -ENOMEM;
1891
Dean Anderson38f993a2008-06-26 23:15:51 -03001892 if (!bOut) {
1893 r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
1894 Request,
1895 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
1896 USB_DIR_IN,
Mauro Carvalho Chehabdb65c492016-10-10 11:11:13 -03001897 Value, Index, buf,
Dean Anderson38f993a2008-06-26 23:15:51 -03001898 TransferBufferLength, HZ * 5);
Mauro Carvalho Chehabdb65c492016-10-10 11:11:13 -03001899
1900 if (r >= 0)
1901 memcpy(TransferBuffer, buf, TransferBufferLength);
Dean Anderson38f993a2008-06-26 23:15:51 -03001902 } else {
Mauro Carvalho Chehabdb65c492016-10-10 11:11:13 -03001903 memcpy(buf, TransferBuffer, TransferBufferLength);
Dean Anderson38f993a2008-06-26 23:15:51 -03001904 r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
1905 Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Mauro Carvalho Chehabdb65c492016-10-10 11:11:13 -03001906 Value, Index, buf,
Dean Anderson38f993a2008-06-26 23:15:51 -03001907 TransferBufferLength, HZ * 5);
1908 }
Mauro Carvalho Chehabdb65c492016-10-10 11:11:13 -03001909 kfree(buf);
Dean Anderson38f993a2008-06-26 23:15:51 -03001910 return r;
1911}
1912
1913/*
1914 * retrieve FX2 firmware version. future use.
1915 * @param dev pointer to device extension
1916 * @return -1 for fail, else returns firmware version as an int(16 bits)
1917 */
1918static int s2255_get_fx2fw(struct s2255_dev *dev)
1919{
1920 int fw;
1921 int ret;
1922 unsigned char transBuffer[64];
1923 ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
1924 S2255_VR_IN);
1925 if (ret < 0)
sensoray-devf5402002014-01-29 15:24:07 -03001926 dprintk(dev, 2, "get fw error: %x\n", ret);
Dean Anderson38f993a2008-06-26 23:15:51 -03001927 fw = transBuffer[0] + (transBuffer[1] << 8);
sensoray-devf5402002014-01-29 15:24:07 -03001928 dprintk(dev, 2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
Dean Anderson38f993a2008-06-26 23:15:51 -03001929 return fw;
1930}
1931
1932/*
1933 * Create the system ring buffer to copy frames into from the
1934 * usb read pipe.
1935 */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001936static int s2255_create_sys_buffers(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03001937{
1938 unsigned long i;
1939 unsigned long reqsize;
Dean Anderson5e950fa2014-02-04 18:16:24 -03001940 vc->buffer.dwFrames = SYS_FRAMES;
Dean Anderson38f993a2008-06-26 23:15:51 -03001941 /* always allocate maximum size(PAL) for system buffers */
1942 reqsize = SYS_FRAMES_MAXSIZE;
1943
1944 if (reqsize > SYS_FRAMES_MAXSIZE)
1945 reqsize = SYS_FRAMES_MAXSIZE;
1946
1947 for (i = 0; i < SYS_FRAMES; i++) {
1948 /* allocate the frames */
Dean Anderson5e950fa2014-02-04 18:16:24 -03001949 vc->buffer.frame[i].lpvbits = vmalloc(reqsize);
1950 vc->buffer.frame[i].size = reqsize;
1951 if (vc->buffer.frame[i].lpvbits == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03001952 pr_info("out of memory. using less frames\n");
Dean Anderson5e950fa2014-02-04 18:16:24 -03001953 vc->buffer.dwFrames = i;
Dean Anderson38f993a2008-06-26 23:15:51 -03001954 break;
1955 }
1956 }
1957
1958 /* make sure internal states are set */
1959 for (i = 0; i < SYS_FRAMES; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03001960 vc->buffer.frame[i].ulState = 0;
1961 vc->buffer.frame[i].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03001962 }
1963
Dean Anderson5e950fa2014-02-04 18:16:24 -03001964 vc->cur_frame = 0;
1965 vc->last_frame = -1;
Dean Anderson38f993a2008-06-26 23:15:51 -03001966 return 0;
1967}
1968
Dean Anderson5e950fa2014-02-04 18:16:24 -03001969static int s2255_release_sys_buffers(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03001970{
1971 unsigned long i;
Dean Anderson38f993a2008-06-26 23:15:51 -03001972 for (i = 0; i < SYS_FRAMES; i++) {
Markus Elfring83f56f72014-11-20 09:26:36 -03001973 vfree(vc->buffer.frame[i].lpvbits);
Dean Anderson5e950fa2014-02-04 18:16:24 -03001974 vc->buffer.frame[i].lpvbits = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03001975 }
1976 return 0;
1977}
1978
1979static int s2255_board_init(struct s2255_dev *dev)
1980{
Dean Anderson38f993a2008-06-26 23:15:51 -03001981 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
1982 int fw_ver;
Dean Andersonab85c6a2010-04-08 23:39:12 -03001983 int j;
1984 struct s2255_pipeinfo *pipe = &dev->pipe;
sensoray-devf5402002014-01-29 15:24:07 -03001985 dprintk(dev, 4, "board init: %p", dev);
Dean Andersonab85c6a2010-04-08 23:39:12 -03001986 memset(pipe, 0, sizeof(*pipe));
1987 pipe->dev = dev;
1988 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
1989 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
Dean Anderson38f993a2008-06-26 23:15:51 -03001990
Dean Andersonab85c6a2010-04-08 23:39:12 -03001991 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
1992 GFP_KERNEL);
1993 if (pipe->transfer_buffer == NULL) {
sensoray-devf5402002014-01-29 15:24:07 -03001994 dprintk(dev, 1, "out of memory!\n");
Dean Andersonab85c6a2010-04-08 23:39:12 -03001995 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03001996 }
Dean Anderson38f993a2008-06-26 23:15:51 -03001997 /* query the firmware */
1998 fw_ver = s2255_get_fx2fw(dev);
1999
sensoray-devf5402002014-01-29 15:24:07 -03002000 pr_info("s2255: usb firmware version %d.%d\n",
2001 (fw_ver >> 8) & 0xff,
2002 fw_ver & 0xff);
Dean Andersonabce21f2009-04-23 16:04:41 -03002003
2004 if (fw_ver < S2255_CUR_USB_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002005 pr_info("s2255: newer USB firmware available\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002006
2007 for (j = 0; j < MAX_CHANNELS; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002008 struct s2255_vc *vc = &dev->vc[j];
Dean Anderson5e950fa2014-02-04 18:16:24 -03002009 vc->mode = mode_def;
Dean Anderson5a34d9d2010-03-05 19:59:48 -03002010 if (dev->pid == 0x2257 && j > 1)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002011 vc->mode.color |= (1 << 16);
2012 vc->jpegqual = S2255_DEF_JPEG_QUAL;
2013 vc->width = LINE_SZ_4CIFS_NTSC;
2014 vc->height = NUM_LINES_4CIFS_NTSC * 2;
2015 vc->std = V4L2_STD_NTSC_M;
2016 vc->fmt = &formats[0];
2017 vc->mode.restart = 1;
2018 vc->req_image_size = get_transfer_size(&mode_def);
2019 vc->frame_count = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002020 /* create the system buffers */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002021 s2255_create_sys_buffers(vc);
Dean Anderson38f993a2008-06-26 23:15:51 -03002022 }
2023 /* start read pipe */
2024 s2255_start_readpipe(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002025 dprintk(dev, 1, "%s: success\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002026 return 0;
2027}
2028
2029static int s2255_board_shutdown(struct s2255_dev *dev)
2030{
2031 u32 i;
sensoray-devf5402002014-01-29 15:24:07 -03002032 dprintk(dev, 1, "%s: dev: %p", __func__, dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002033
2034 for (i = 0; i < MAX_CHANNELS; i++) {
sensoray-dev340a30c2014-02-12 17:25:45 -03002035 if (vb2_is_streaming(&dev->vc[i].vb_vidq))
Dean Anderson5e950fa2014-02-04 18:16:24 -03002036 s2255_stop_acquire(&dev->vc[i]);
Dean Anderson38f993a2008-06-26 23:15:51 -03002037 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002038 s2255_stop_readpipe(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002039 for (i = 0; i < MAX_CHANNELS; i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002040 s2255_release_sys_buffers(&dev->vc[i]);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002041 /* release transfer buffer */
2042 kfree(dev->pipe.transfer_buffer);
Dean Anderson38f993a2008-06-26 23:15:51 -03002043 return 0;
2044}
2045
2046static void read_pipe_completion(struct urb *purb)
2047{
2048 struct s2255_pipeinfo *pipe_info;
2049 struct s2255_dev *dev;
2050 int status;
2051 int pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002052 pipe_info = purb->context;
Dean Anderson38f993a2008-06-26 23:15:51 -03002053 if (pipe_info == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002054 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002055 return;
2056 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002057 dev = pipe_info->dev;
2058 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002059 dev_err(&purb->dev->dev, "no context!\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002060 return;
2061 }
2062 status = purb->status;
Dean Andersonb02064c2009-04-30 12:29:38 -03002063 /* if shutting down, do not resubmit, exit immediately */
2064 if (status == -ESHUTDOWN) {
sensoray-devf5402002014-01-29 15:24:07 -03002065 dprintk(dev, 2, "%s: err shutdown\n", __func__);
Dean Andersonb02064c2009-04-30 12:29:38 -03002066 pipe_info->err_count++;
Dean Anderson38f993a2008-06-26 23:15:51 -03002067 return;
2068 }
2069
2070 if (pipe_info->state == 0) {
sensoray-devf5402002014-01-29 15:24:07 -03002071 dprintk(dev, 2, "%s: exiting USB pipe", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002072 return;
2073 }
2074
Dean Andersonb02064c2009-04-30 12:29:38 -03002075 if (status == 0)
2076 s2255_read_video_callback(dev, pipe_info);
2077 else {
2078 pipe_info->err_count++;
sensoray-devf5402002014-01-29 15:24:07 -03002079 dprintk(dev, 1, "%s: failed URB %d\n", __func__, status);
Dean Andersonb02064c2009-04-30 12:29:38 -03002080 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002081
Dean Anderson38f993a2008-06-26 23:15:51 -03002082 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2083 /* reuse urb */
2084 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2085 pipe,
2086 pipe_info->transfer_buffer,
2087 pipe_info->cur_transfer_size,
2088 read_pipe_completion, pipe_info);
2089
2090 if (pipe_info->state != 0) {
sensoray-devf5402002014-01-29 15:24:07 -03002091 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC))
Dean Anderson38f993a2008-06-26 23:15:51 -03002092 dev_err(&dev->udev->dev, "error submitting urb\n");
Dean Anderson38f993a2008-06-26 23:15:51 -03002093 } else {
sensoray-devf5402002014-01-29 15:24:07 -03002094 dprintk(dev, 2, "%s :complete state 0\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002095 }
2096 return;
2097}
2098
2099static int s2255_start_readpipe(struct s2255_dev *dev)
2100{
2101 int pipe;
2102 int retval;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002103 struct s2255_pipeinfo *pipe_info = &dev->pipe;
Dean Anderson38f993a2008-06-26 23:15:51 -03002104 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
sensoray-devf5402002014-01-29 15:24:07 -03002105 dprintk(dev, 2, "%s: IN %d\n", __func__, dev->read_endpoint);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002106 pipe_info->state = 1;
2107 pipe_info->err_count = 0;
2108 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
Wolfram Sangfc56da72016-08-11 18:03:58 -03002109 if (!pipe_info->stream_urb)
Dean Andersonab85c6a2010-04-08 23:39:12 -03002110 return -ENOMEM;
Dean Andersonab85c6a2010-04-08 23:39:12 -03002111 /* transfer buffer allocated in board_init */
2112 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2113 pipe,
2114 pipe_info->transfer_buffer,
2115 pipe_info->cur_transfer_size,
2116 read_pipe_completion, pipe_info);
Dean Andersonab85c6a2010-04-08 23:39:12 -03002117 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2118 if (retval) {
sensoray-devf5402002014-01-29 15:24:07 -03002119 pr_err("s2255: start read pipe failed\n");
Dean Andersonab85c6a2010-04-08 23:39:12 -03002120 return retval;
2121 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002122 return 0;
2123}
2124
2125/* starts acquisition process */
Dean Anderson5e950fa2014-02-04 18:16:24 -03002126static int s2255_start_acquire(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03002127{
Dean Anderson38f993a2008-06-26 23:15:51 -03002128 int res;
2129 unsigned long chn_rev;
2130 int j;
Dean Anderson5e950fa2014-02-04 18:16:24 -03002131 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03002132 __le32 *buffer = dev->cmdbuf;
Dean Anderson38f993a2008-06-26 23:15:51 -03002133
Dean Anderson47d8c882014-02-05 15:43:51 -03002134 mutex_lock(&dev->cmdlock);
2135 chn_rev = G_chnmap[vc->idx];
Dean Anderson5e950fa2014-02-04 18:16:24 -03002136 vc->last_frame = -1;
2137 vc->bad_payload = 0;
2138 vc->cur_frame = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002139 for (j = 0; j < SYS_FRAMES; j++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002140 vc->buffer.frame[j].ulState = 0;
2141 vc->buffer.frame[j].cur_size = 0;
Dean Anderson38f993a2008-06-26 23:15:51 -03002142 }
2143
2144 /* send the start command */
Dean Anderson47d8c882014-02-05 15:43:51 -03002145 buffer[0] = IN_DATA_TOKEN;
2146 buffer[1] = (__le32) cpu_to_le32(chn_rev);
2147 buffer[2] = CMD_START;
Dean Anderson38f993a2008-06-26 23:15:51 -03002148 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2149 if (res != 0)
2150 dev_err(&dev->udev->dev, "CMD_START error\n");
2151
Dean Anderson5e950fa2014-02-04 18:16:24 -03002152 dprintk(dev, 2, "start acquire exit[%d] %d\n", vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03002153 mutex_unlock(&dev->cmdlock);
Dean Anderson6a5b63b2014-02-05 15:58:20 -03002154 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002155}
2156
Dean Anderson5e950fa2014-02-04 18:16:24 -03002157static int s2255_stop_acquire(struct s2255_vc *vc)
Dean Anderson38f993a2008-06-26 23:15:51 -03002158{
Dean Anderson38f993a2008-06-26 23:15:51 -03002159 int res;
2160 unsigned long chn_rev;
Dean Anderson5e950fa2014-02-04 18:16:24 -03002161 struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
Dean Anderson47d8c882014-02-05 15:43:51 -03002162 __le32 *buffer = dev->cmdbuf;
2163
2164 mutex_lock(&dev->cmdlock);
Dean Anderson5e950fa2014-02-04 18:16:24 -03002165 chn_rev = G_chnmap[vc->idx];
Dean Anderson38f993a2008-06-26 23:15:51 -03002166 /* send the stop command */
Dean Anderson47d8c882014-02-05 15:43:51 -03002167 buffer[0] = IN_DATA_TOKEN;
2168 buffer[1] = (__le32) cpu_to_le32(chn_rev);
2169 buffer[2] = CMD_STOP;
2170
Dean Anderson38f993a2008-06-26 23:15:51 -03002171 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
Dean Anderson38f993a2008-06-26 23:15:51 -03002172 if (res != 0)
2173 dev_err(&dev->udev->dev, "CMD_STOP error\n");
Dean Anderson47d8c882014-02-05 15:43:51 -03002174
Dean Anderson5e950fa2014-02-04 18:16:24 -03002175 dprintk(dev, 4, "%s: chn %d, res %d\n", __func__, vc->idx, res);
Dean Anderson47d8c882014-02-05 15:43:51 -03002176 mutex_unlock(&dev->cmdlock);
Dean Anderson14d96262008-08-25 13:58:55 -03002177 return res;
Dean Anderson38f993a2008-06-26 23:15:51 -03002178}
2179
2180static void s2255_stop_readpipe(struct s2255_dev *dev)
2181{
Dean Andersonab85c6a2010-04-08 23:39:12 -03002182 struct s2255_pipeinfo *pipe = &dev->pipe;
Dan Carpenter8b661b52010-05-05 03:00:47 -03002183
Dean Andersonab85c6a2010-04-08 23:39:12 -03002184 pipe->state = 0;
2185 if (pipe->stream_urb) {
2186 /* cancel urb */
2187 usb_kill_urb(pipe->stream_urb);
2188 usb_free_urb(pipe->stream_urb);
2189 pipe->stream_urb = NULL;
Dean Anderson38f993a2008-06-26 23:15:51 -03002190 }
sensoray-devf5402002014-01-29 15:24:07 -03002191 dprintk(dev, 4, "%s", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002192 return;
2193}
2194
Dean Ae2a06702017-11-03 16:11:03 -04002195static void s2255_fwload_start(struct s2255_dev *dev)
Dean Anderson38f993a2008-06-26 23:15:51 -03002196{
Dean Ae2a06702017-11-03 16:11:03 -04002197 s2255_reset_dsppower(dev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002198 dev->fw_data->fw_size = dev->fw_data->fw->size;
2199 atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
2200 memcpy(dev->fw_data->pfw_data,
2201 dev->fw_data->fw->data, CHUNK_SIZE);
2202 dev->fw_data->fw_loaded = CHUNK_SIZE;
2203 usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
2204 usb_sndbulkpipe(dev->udev, 2),
2205 dev->fw_data->pfw_data,
2206 CHUNK_SIZE, s2255_fwchunk_complete,
2207 dev->fw_data);
2208 mod_timer(&dev->timer, jiffies + HZ);
2209}
2210
2211/* standard usb probe function */
2212static int s2255_probe(struct usb_interface *interface,
2213 const struct usb_device_id *id)
2214{
2215 struct s2255_dev *dev = NULL;
2216 struct usb_host_interface *iface_desc;
2217 struct usb_endpoint_descriptor *endpoint;
2218 int i;
2219 int retval = -ENOMEM;
Dean Anderson14d96262008-08-25 13:58:55 -03002220 __le32 *pdata;
2221 int fw_size;
Dean Anderson47d8c882014-02-05 15:43:51 -03002222
Dean Anderson38f993a2008-06-26 23:15:51 -03002223 /* allocate memory for our device state and initialize it to zero */
2224 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2225 if (dev == NULL) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002226 s2255_dev_err(&interface->dev, "out of memory\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002227 return -ENOMEM;
Dean Anderson38f993a2008-06-26 23:15:51 -03002228 }
Dean Anderson47d8c882014-02-05 15:43:51 -03002229
2230 dev->cmdbuf = kzalloc(S2255_CMDBUF_SIZE, GFP_KERNEL);
2231 if (dev->cmdbuf == NULL) {
2232 s2255_dev_err(&interface->dev, "out of memory\n");
Daeseok Youne21c94e2014-05-08 19:57:18 -03002233 goto errorFWDATA1;
Dean Anderson47d8c882014-02-05 15:43:51 -03002234 }
2235
Dean Andersonfe85ce92010-06-01 19:12:07 -03002236 atomic_set(&dev->num_channels, 0);
Hans Verkuilff3ec572014-08-20 19:25:34 -03002237 dev->pid = id->idProduct;
Dean Anderson38f993a2008-06-26 23:15:51 -03002238 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2239 if (!dev->fw_data)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002240 goto errorFWDATA1;
Dean Anderson38f993a2008-06-26 23:15:51 -03002241 mutex_init(&dev->lock);
Dean Anderson47d8c882014-02-05 15:43:51 -03002242 mutex_init(&dev->cmdlock);
Dean Anderson38f993a2008-06-26 23:15:51 -03002243 /* grab usb_device and save it */
2244 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2245 if (dev->udev == NULL) {
2246 dev_err(&interface->dev, "null usb device\n");
2247 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002248 goto errorUDEV;
Dean Anderson38f993a2008-06-26 23:15:51 -03002249 }
sensoray-devf5402002014-01-29 15:24:07 -03002250 dev_dbg(&interface->dev, "dev: %p, udev %p interface %p\n",
2251 dev, dev->udev, interface);
Dean Anderson38f993a2008-06-26 23:15:51 -03002252 dev->interface = interface;
2253 /* set up the endpoint information */
2254 iface_desc = interface->cur_altsetting;
sensoray-devf5402002014-01-29 15:24:07 -03002255 dev_dbg(&interface->dev, "num EP: %d\n",
2256 iface_desc->desc.bNumEndpoints);
Dean Anderson38f993a2008-06-26 23:15:51 -03002257 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2258 endpoint = &iface_desc->endpoint[i].desc;
2259 if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
2260 /* we found the bulk in endpoint */
2261 dev->read_endpoint = endpoint->bEndpointAddress;
2262 }
2263 }
2264
2265 if (!dev->read_endpoint) {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002266 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002267 goto errorEP;
Dean Anderson38f993a2008-06-26 23:15:51 -03002268 }
Kees Cook74ee0472017-10-24 11:23:21 -04002269 timer_setup(&dev->timer, s2255_timer, 0);
Dean Anderson38f993a2008-06-26 23:15:51 -03002270 init_waitqueue_head(&dev->fw_data->wait_fw);
Dean Anderson4de39f52010-03-03 19:39:19 -03002271 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002272 struct s2255_vc *vc = &dev->vc[i];
2273 vc->idx = i;
2274 vc->dev = dev;
2275 init_waitqueue_head(&vc->wait_setmode);
2276 init_waitqueue_head(&vc->wait_vidstatus);
sensoray-dev340a30c2014-02-12 17:25:45 -03002277 spin_lock_init(&vc->qlock);
2278 mutex_init(&vc->vb_lock);
Dean Anderson4de39f52010-03-03 19:39:19 -03002279 }
Dean Anderson38f993a2008-06-26 23:15:51 -03002280
2281 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
Wolfram Sangfc56da72016-08-11 18:03:58 -03002282 if (!dev->fw_data->fw_urb)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002283 goto errorFWURB;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002284
Dean Anderson38f993a2008-06-26 23:15:51 -03002285 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2286 if (!dev->fw_data->pfw_data) {
2287 dev_err(&interface->dev, "out of memory!\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002288 goto errorFWDATA2;
Dean Anderson38f993a2008-06-26 23:15:51 -03002289 }
2290 /* load the first chunk */
2291 if (request_firmware(&dev->fw_data->fw,
2292 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
sensoray-devf5402002014-01-29 15:24:07 -03002293 dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n");
Dean Andersonff7e22d2010-04-08 23:38:07 -03002294 goto errorREQFW;
Dean Anderson38f993a2008-06-26 23:15:51 -03002295 }
Dean Anderson14d96262008-08-25 13:58:55 -03002296 /* check the firmware is valid */
2297 fw_size = dev->fw_data->fw->size;
2298 pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
Dean Anderson38f993a2008-06-26 23:15:51 -03002299
Dean Anderson14d96262008-08-25 13:58:55 -03002300 if (*pdata != S2255_FW_MARKER) {
sensoray-devf5402002014-01-29 15:24:07 -03002301 dev_err(&interface->dev, "Firmware invalid.\n");
Dean Anderson14d96262008-08-25 13:58:55 -03002302 retval = -ENODEV;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002303 goto errorFWMARKER;
Dean Anderson14d96262008-08-25 13:58:55 -03002304 } else {
2305 /* make sure firmware is the latest */
2306 __le32 *pRel;
2307 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
sensoray-devf5402002014-01-29 15:24:07 -03002308 pr_info("s2255 dsp fw version %x\n", le32_to_cpu(*pRel));
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002309 dev->dsp_fw_ver = le32_to_cpu(*pRel);
2310 if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
sensoray-devf5402002014-01-29 15:24:07 -03002311 pr_info("s2255: f2255usb.bin out of date.\n");
Dan Carpenter3b2a6302012-02-17 02:44:10 -03002312 if (dev->pid == 0x2257 &&
2313 dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
sensoray-devf5402002014-01-29 15:24:07 -03002314 pr_warn("2257 needs firmware %d or above.\n",
2315 S2255_MIN_DSP_COLORFILTER);
Dean Anderson14d96262008-08-25 13:58:55 -03002316 }
Dean Anderson14d96262008-08-25 13:58:55 -03002317 usb_reset_device(dev->udev);
Dean Anderson38f993a2008-06-26 23:15:51 -03002318 /* load 2255 board specific */
Dean Andersonabce21f2009-04-23 16:04:41 -03002319 retval = s2255_board_init(dev);
2320 if (retval)
Dean Andersonff7e22d2010-04-08 23:38:07 -03002321 goto errorBOARDINIT;
Dean Ae2a06702017-11-03 16:11:03 -04002322 s2255_fwload_start(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002323 /* loads v4l specific */
2324 retval = s2255_probe_v4l(dev);
2325 if (retval)
Dean Anderson3a67b5cc2010-04-08 23:52:20 -03002326 goto errorBOARDINIT;
Dean Anderson38f993a2008-06-26 23:15:51 -03002327 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2328 return 0;
Dean Andersonff7e22d2010-04-08 23:38:07 -03002329errorBOARDINIT:
2330 s2255_board_shutdown(dev);
2331errorFWMARKER:
2332 release_firmware(dev->fw_data->fw);
2333errorREQFW:
2334 kfree(dev->fw_data->pfw_data);
2335errorFWDATA2:
2336 usb_free_urb(dev->fw_data->fw_urb);
2337errorFWURB:
Kirill Tkhai9f6be2b2014-04-17 17:47:04 -03002338 del_timer_sync(&dev->timer);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002339errorEP:
2340 usb_put_dev(dev->udev);
2341errorUDEV:
2342 kfree(dev->fw_data);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002343 mutex_destroy(&dev->lock);
2344errorFWDATA1:
Dean Anderson47d8c882014-02-05 15:43:51 -03002345 kfree(dev->cmdbuf);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002346 kfree(dev);
sensoray-devf5402002014-01-29 15:24:07 -03002347 pr_warn("Sensoray 2255 driver load failed: 0x%x\n", retval);
Dean Anderson38f993a2008-06-26 23:15:51 -03002348 return retval;
2349}
2350
2351/* disconnect routine. when board is removed physically or with rmmod */
2352static void s2255_disconnect(struct usb_interface *interface)
2353{
Dean Anderson65c6edb2010-04-20 17:21:32 -03002354 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
Dean Anderson14d96262008-08-25 13:58:55 -03002355 int i;
Dean Andersonfe85ce92010-06-01 19:12:07 -03002356 int channels = atomic_read(&dev->num_channels);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002357 mutex_lock(&dev->lock);
Dean Andersonfe85ce92010-06-01 19:12:07 -03002358 v4l2_device_disconnect(&dev->v4l2_dev);
Pete Eberleina19a5cd2010-12-20 19:18:59 -03002359 mutex_unlock(&dev->lock);
Dean Andersond62e85a2010-04-09 19:54:26 -03002360 /*see comments in the uvc_driver.c usb disconnect function */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002361 atomic_inc(&dev->num_channels);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002362 /* unregister each video device. */
Dean Andersonfe85ce92010-06-01 19:12:07 -03002363 for (i = 0; i < channels; i++)
Dean Anderson5e950fa2014-02-04 18:16:24 -03002364 video_unregister_device(&dev->vc[i].vdev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002365 /* wake up any of our timers */
Dean Anderson14d96262008-08-25 13:58:55 -03002366 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2367 wake_up(&dev->fw_data->wait_fw);
2368 for (i = 0; i < MAX_CHANNELS; i++) {
Dean Anderson5e950fa2014-02-04 18:16:24 -03002369 dev->vc[i].setmode_ready = 1;
2370 wake_up(&dev->vc[i].wait_setmode);
2371 dev->vc[i].vidstatus_ready = 1;
2372 wake_up(&dev->vc[i].wait_vidstatus);
Dean Anderson14d96262008-08-25 13:58:55 -03002373 }
Dean Andersonfe85ce92010-06-01 19:12:07 -03002374 if (atomic_dec_and_test(&dev->num_channels))
Dean Andersond62e85a2010-04-09 19:54:26 -03002375 s2255_destroy(dev);
Dean Andersonff7e22d2010-04-08 23:38:07 -03002376 dev_info(&interface->dev, "%s\n", __func__);
Dean Anderson38f993a2008-06-26 23:15:51 -03002377}
2378
2379static struct usb_driver s2255_driver = {
Mauro Carvalho Chehabbe9ed512009-01-08 09:13:42 -03002380 .name = S2255_DRIVER_NAME,
Dean Anderson38f993a2008-06-26 23:15:51 -03002381 .probe = s2255_probe,
2382 .disconnect = s2255_disconnect,
2383 .id_table = s2255_table,
2384};
2385
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002386module_usb_driver(s2255_driver);
Dean Anderson38f993a2008-06-26 23:15:51 -03002387
2388MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
2389MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
2390MODULE_LICENSE("GPL");
Mauro Carvalho Chehab64dc3c12011-06-25 11:28:37 -03002391MODULE_VERSION(S2255_VERSION);
Tim Gardner1bec9822012-07-24 16:52:27 -03002392MODULE_FIRMWARE(FIRMWARE_FILE_NAME);