Blame view

drivers/media/video/s2255drv.c 75.5 KB
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1
2
3
  /*
   *  s2255drv.c - a driver for the Sensoray 2255 USB video capture device
   *
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
4
   *   Copyright (C) 2007-2010 by Sensoray Company Inc.
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
   *                              Dean Anderson
   *
   * Some video buffer code based on vivi driver:
   *
   * Sensoray 2255 device supports 4 simultaneous channels.
   * The channels are not "crossbar" inputs, they are physically
   * attached to separate video decoders.
   *
   * Because of USB2.0 bandwidth limitations. There is only a
   * certain amount of data which may be transferred at one time.
   *
   * Example maximum bandwidth utilization:
   *
   * -full size, color mode YUYV or YUV422P: 2 channels at once
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
19
   * -full or half size Grey scale: all 4 channels at once
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
20
   * -half size, color mode YUYV or YUV422P: all 4 channels at once
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
21
22
   * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
   *  at once.
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   */
  
  #include <linux/module.h>
  #include <linux/firmware.h>
  #include <linux/kernel.h>
  #include <linux/mutex.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
43
  #include <linux/slab.h>
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
44
  #include <linux/videodev2.h>
feb75f071   Hans Verkuil   V4L/DVB (8504): s...
45
  #include <linux/mm.h>
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
46
47
  #include <media/videobuf-vmalloc.h>
  #include <media/v4l2-common.h>
3a67b5cc6   Dean Anderson   V4L/DVB: s2255drv...
48
  #include <media/v4l2-device.h>
35ea11ff8   Hans Verkuil   V4L/DVB (8430): v...
49
  #include <media/v4l2-ioctl.h>
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
50
51
  #include <linux/vmalloc.h>
  #include <linux/usb.h>
64dc3c1a9   Mauro Carvalho Chehab   [media] Stop usin...
52
  #define S2255_VERSION		"1.22.1"
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
53
  #define FIRMWARE_FILE_NAME "f2255usb.bin"
22b88d48a   Dean Anderson   V4L/DVB (8845): s...
54
55
  /* default JPEG quality */
  #define S2255_DEF_JPEG_QUAL     50
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
56
57
58
59
60
61
62
63
64
  /* vendor request in */
  #define S2255_VR_IN		0
  /* vendor request out */
  #define S2255_VR_OUT		1
  /* firmware query */
  #define S2255_VR_FW		0x30
  /* USB endpoint number for configuring the device */
  #define S2255_CONFIG_EP         2
  /* maximum time for DSP to start responding after last FW word loaded(ms) */
14d962602   Dean Anderson   V4L/DVB (8752): s...
65
  #define S2255_DSP_BOOTTIME      800
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
66
  /* maximum time to wait for firmware to load (ms) */
3f8d6f73d   Dean Anderson   V4L/DVB (8317): S...
67
  #define S2255_LOAD_TIMEOUT      (5000 + S2255_DSP_BOOTTIME)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
68
  #define S2255_DEF_BUFS          16
14d962602   Dean Anderson   V4L/DVB (8752): s...
69
  #define S2255_SETMODE_TIMEOUT   500
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
70
  #define S2255_VIDSTATUS_TIMEOUT 350
3fa006052   Dean Anderson   V4L/DVB: s2255drv...
71
72
73
74
75
  #define S2255_MARKER_FRAME	cpu_to_le32(0x2255DA4AL)
  #define S2255_MARKER_RESPONSE	cpu_to_le32(0x2255ACACL)
  #define S2255_RESPONSE_SETMODE  cpu_to_le32(0x01)
  #define S2255_RESPONSE_FW       cpu_to_le32(0x10)
  #define S2255_RESPONSE_STATUS   cpu_to_le32(0x20)
14d962602   Dean Anderson   V4L/DVB (8752): s...
76
  #define S2255_USB_XFER_SIZE	(16 * 1024)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
77
  #define MAX_CHANNELS		4
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
78
79
  #define SYS_FRAMES		4
  /* maximum size is PAL full size plus room for the marker header(s) */
14d962602   Dean Anderson   V4L/DVB (8752): s...
80
81
  #define SYS_FRAMES_MAXSIZE	(720*288*2*2 + 4096)
  #define DEF_USB_BLOCK		S2255_USB_XFER_SIZE
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  #define LINE_SZ_4CIFS_NTSC	640
  #define LINE_SZ_2CIFS_NTSC	640
  #define LINE_SZ_1CIFS_NTSC	320
  #define LINE_SZ_4CIFS_PAL	704
  #define LINE_SZ_2CIFS_PAL	704
  #define LINE_SZ_1CIFS_PAL	352
  #define NUM_LINES_4CIFS_NTSC	240
  #define NUM_LINES_2CIFS_NTSC	240
  #define NUM_LINES_1CIFS_NTSC	240
  #define NUM_LINES_4CIFS_PAL	288
  #define NUM_LINES_2CIFS_PAL	288
  #define NUM_LINES_1CIFS_PAL	288
  #define LINE_SZ_DEF		640
  #define NUM_LINES_DEF		240
  
  
  /* predefined settings */
  #define FORMAT_NTSC	1
  #define FORMAT_PAL	2
  
  #define SCALE_4CIFS	1	/* 640x480(NTSC) or 704x576(PAL) */
  #define SCALE_2CIFS	2	/* 640x240(NTSC) or 704x288(PAL) */
  #define SCALE_1CIFS	3	/* 320x240(NTSC) or 352x288(PAL) */
7d8535329   Dean Anderson   V4L/DVB (11851): ...
105
106
  /* SCALE_4CIFSI is the 2 fields interpolated into one */
  #define SCALE_4CIFSI	4	/* 640x480(NTSC) or 704x576(PAL) high quality */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
107
108
109
110
  
  #define COLOR_YUVPL	1	/* YUV planar */
  #define COLOR_YUVPK	2	/* YUV packed */
  #define COLOR_Y8	4	/* monochrome */
14d962602   Dean Anderson   V4L/DVB (8752): s...
111
  #define COLOR_JPG       5       /* JPEG */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
112

5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
113
114
115
  #define MASK_COLOR       0x000000ff
  #define MASK_JPG_QUALITY 0x0000ff00
  #define MASK_INPUT_TYPE  0x000f0000
8a8cc952d   Sensoray Linux Development   [media] s2255drv:...
116
  /* frame decimation. */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
  #define FDEC_1		1	/* capture every frame. default */
  #define FDEC_2		2	/* capture every 2nd frame */
  #define FDEC_3		3	/* capture every 3rd frame */
  #define FDEC_5		5	/* capture every 5th frame */
  
  /*-------------------------------------------------------
   * Default mode parameters.
   *-------------------------------------------------------*/
  #define DEF_SCALE	SCALE_4CIFS
  #define DEF_COLOR	COLOR_YUVPL
  #define DEF_FDEC	FDEC_1
  #define DEF_BRIGHT	0
  #define DEF_CONTRAST	0x5c
  #define DEF_SATURATION	0x80
  #define DEF_HUE		0
  
  /* usb config commands */
3fa006052   Dean Anderson   V4L/DVB: s2255drv...
134
135
136
137
138
139
  #define IN_DATA_TOKEN	cpu_to_le32(0x2255c0de)
  #define CMD_2255	cpu_to_le32(0xc2255000)
  #define CMD_SET_MODE	cpu_to_le32((CMD_2255 | 0x10))
  #define CMD_START	cpu_to_le32((CMD_2255 | 0x20))
  #define CMD_STOP	cpu_to_le32((CMD_2255 | 0x30))
  #define CMD_STATUS	cpu_to_le32((CMD_2255 | 0x40))
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
  
  struct s2255_mode {
  	u32 format;	/* input video format (NTSC, PAL) */
  	u32 scale;	/* output video scale */
  	u32 color;	/* output video color format */
  	u32 fdec;	/* frame decimation */
  	u32 bright;	/* brightness */
  	u32 contrast;	/* contrast */
  	u32 saturation;	/* saturation */
  	u32 hue;	/* hue (NTSC only)*/
  	u32 single;	/* capture 1 frame at a time (!=0), continuously (==0)*/
  	u32 usb_block;	/* block size. should be 4096 of DEF_USB_BLOCK */
  	u32 restart;	/* if DSP requires restart */
  };
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
154

14d962602   Dean Anderson   V4L/DVB (8752): s...
155
156
  #define S2255_READ_IDLE		0
  #define S2255_READ_FRAME	1
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
157

14d962602   Dean Anderson   V4L/DVB (8752): s...
158
  /* frame structure */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
159
160
  struct s2255_framei {
  	unsigned long size;
14d962602   Dean Anderson   V4L/DVB (8752): s...
161
  	unsigned long ulState;	/* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
162
163
164
165
166
167
168
169
170
171
172
173
  	void *lpvbits;		/* image data */
  	unsigned long cur_size;	/* current data copied to it */
  };
  
  /* image buffer structure */
  struct s2255_bufferi {
  	unsigned long dwFrames;			/* number of frames in buffer */
  	struct s2255_framei frame[SYS_FRAMES];	/* array of FRAME structures */
  };
  
  #define DEF_MODEI_NTSC_CONT	{FORMAT_NTSC, DEF_SCALE, DEF_COLOR,	\
  			DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
3f8d6f73d   Dean Anderson   V4L/DVB (8317): S...
174
  			DEF_HUE, 0, DEF_USB_BLOCK, 0}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
175
176
177
  
  struct s2255_dmaqueue {
  	struct list_head	active;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
178
  	struct s2255_dev	*dev;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
179
180
181
182
183
184
185
  };
  
  /* for firmware loading, fw_state */
  #define S2255_FW_NOTLOADED	0
  #define S2255_FW_LOADED_DSPWAIT	1
  #define S2255_FW_SUCCESS	2
  #define S2255_FW_FAILED		3
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
186
  #define S2255_FW_DISCONNECTING  4
deaf53e3c   Harvey Harrison   V4L/DVB (9635): v...
187
  #define S2255_FW_MARKER		cpu_to_le32(0x22552f2f)
14d962602   Dean Anderson   V4L/DVB (8752): s...
188
189
190
  /* 2255 read states */
  #define S2255_READ_IDLE         0
  #define S2255_READ_FRAME        1
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
191
192
193
194
195
196
197
  struct s2255_fw {
  	int		      fw_loaded;
  	int		      fw_size;
  	struct urb	      *fw_urb;
  	atomic_t	      fw_state;
  	void		      *pfw_data;
  	wait_queue_head_t     wait_fw;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
198
199
200
201
202
203
204
  	const struct firmware *fw;
  };
  
  struct s2255_pipeinfo {
  	u32 max_transfer_size;
  	u32 cur_transfer_size;
  	u8 *transfer_buffer;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
205
  	u32 state;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
206
207
208
  	void *stream_urb;
  	void *dev;	/* back pointer to s2255_dev struct*/
  	u32 err_count;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
209
  	u32 idx;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
210
211
212
  };
  
  struct s2255_fmt; /*forward declaration */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
  struct s2255_dev;
  
  struct s2255_channel {
  	struct video_device	vdev;
  	int			resources;
  	struct s2255_dmaqueue	vidq;
  	struct s2255_bufferi	buffer;
  	struct s2255_mode	mode;
  	/* jpeg compression */
  	struct v4l2_jpegcompression jc;
  	/* capture parameters (for high quality mode full size) */
  	struct v4l2_captureparm cap_parm;
  	int			cur_frame;
  	int			last_frame;
  
  	int			b_acquire;
  	/* allocated image size */
  	unsigned long		req_image_size;
  	/* received packet size */
  	unsigned long		pkt_size;
  	int			bad_payload;
  	unsigned long		frame_count;
  	/* if JPEG image */
  	int                     jpg_size;
  	/* if channel configured to default state */
  	int                     configured;
  	wait_queue_head_t       wait_setmode;
  	int                     setmode_ready;
  	/* video status items */
  	int                     vidstatus;
  	wait_queue_head_t       wait_vidstatus;
  	int                     vidstatus_ready;
  	unsigned int		width;
  	unsigned int		height;
  	const struct s2255_fmt	*fmt;
  	int idx; /* channel number on device, 0-3 */
  };
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
250
251
  
  struct s2255_dev {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
252
  	struct s2255_channel    channel[MAX_CHANNELS];
65c6edb30   Dean Anderson   V4L/DVB: s2255drv...
253
  	struct v4l2_device 	v4l2_dev;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
254
  	atomic_t                num_channels;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
255
  	int			frames;
a19a5cd7b   Pete Eberlein   [media] s2255drv:...
256
  	struct mutex		lock;	/* channels[].vdev.lock */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
257
  	struct mutex		open_lock;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
258
259
260
  	struct usb_device	*udev;
  	struct usb_interface	*interface;
  	u8			read_endpoint;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
261
262
  	struct timer_list	timer;
  	struct s2255_fw	*fw_data;
ab85c6a33   Dean Anderson   V4L/DVB: s2255drv...
263
  	struct s2255_pipeinfo	pipe;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
264
  	u32			cc;	/* current channel */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
265
  	int			frame_ready;
14d962602   Dean Anderson   V4L/DVB (8752): s...
266
  	int                     chn_ready;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
267
  	spinlock_t              slock;
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
268
269
  	/* dsp firmware version (f2255usb.bin) */
  	int                     dsp_fw_ver;
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
270
  	u16                     pid; /* product id */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
271
  };
65c6edb30   Dean Anderson   V4L/DVB: s2255drv...
272

65c6edb30   Dean Anderson   V4L/DVB: s2255drv...
273
274
275
276
  static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
  {
  	return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
  }
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
  
  struct s2255_fmt {
  	char *name;
  	u32 fourcc;
  	int depth;
  };
  
  /* buffer for one video frame */
  struct s2255_buffer {
  	/* common v4l buffer stuff -- must be first */
  	struct videobuf_buffer vb;
  	const struct s2255_fmt *fmt;
  };
  
  struct s2255_fh {
  	struct s2255_dev	*dev;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
293
294
  	struct videobuf_queue	vb_vidq;
  	enum v4l2_buf_type	type;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
295
296
  	struct s2255_channel	*channel;
  	int			resources;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
297
  };
abce21f40   Dean Anderson   V4L/DVB (11605): ...
298
  /* current cypress EEPROM firmware version */
8a8cc952d   Sensoray Linux Development   [media] s2255drv:...
299
  #define S2255_CUR_USB_FWVER	((3 << 8) | 12)
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
300
  /* current DSP FW version */
8a8cc952d   Sensoray Linux Development   [media] s2255drv:...
301
  #define S2255_CUR_DSP_FWVER     10104
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
302
  /* Need DSP version 5+ for video status feature */
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
303
304
  #define S2255_MIN_DSP_STATUS      5
  #define S2255_MIN_DSP_COLORFILTER 8
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
305
  #define S2255_NORMS		(V4L2_STD_PAL | V4L2_STD_NTSC)
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
  
  /* private V4L2 controls */
  
  /*
   * The following chart displays how COLORFILTER should be set
   *  =========================================================
   *  =     fourcc              =     COLORFILTER             =
   *  =                         ===============================
   *  =                         =   0             =    1      =
   *  =========================================================
   *  =  V4L2_PIX_FMT_GREY(Y8)  = monochrome from = monochrome=
   *  =                         = s-video or      = composite =
   *  =                         = B/W camera      = input     =
   *  =========================================================
   *  =    other                = color, svideo   = color,    =
   *  =                         =                 = composite =
   *  =========================================================
   *
   * Notes:
   *   channels 0-3 on 2255 are composite
   *   channels 0-1 on 2257 are composite, 2-3 are s-video
   * If COLORFILTER is 0 with a composite color camera connected,
   * the output will appear monochrome but hatching
   * will occur.
   * COLORFILTER is different from "color killer" and "color effects"
   * for reasons above.
   */
  #define S2255_V4L2_YC_ON  1
  #define S2255_V4L2_YC_OFF 0
  #define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
336
337
338
339
  /* frame prefix size (sent once every frame) */
  #define PREFIX_SIZE		512
  
  /* Channels on box are in reverse order */
3f8d6f73d   Dean Anderson   V4L/DVB (8317): S...
340
  static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
341

38f993ad8   Dean Anderson   V4L/DVB (8125): T...
342
343
344
345
346
  static int debug;
  static int *s2255_debug = &debug;
  
  static int s2255_start_readpipe(struct s2255_dev *dev);
  static void s2255_stop_readpipe(struct s2255_dev *dev);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
347
348
349
350
351
  static int s2255_start_acquire(struct s2255_channel *channel);
  static int s2255_stop_acquire(struct s2255_channel *channel);
  static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
  			   int jpgsize);
  static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
352
  static int s2255_board_shutdown(struct s2255_dev *dev);
14d962602   Dean Anderson   V4L/DVB (8752): s...
353
  static void s2255_fwload_start(struct s2255_dev *dev, int reset);
d62e85a09   Dean Anderson   V4L/DVB: s2255drv...
354
  static void s2255_destroy(struct s2255_dev *dev);
14d962602   Dean Anderson   V4L/DVB (8752): s...
355
356
357
  static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
  			     u16 index, u16 value, void *buf,
  			     s32 buf_len, int bOut);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
358

be9ed5117   Mauro Carvalho Chehab   V4L/DVB (10298): ...
359
360
361
362
  /* dev_err macro with driver name */
  #define S2255_DRIVER_NAME "s2255"
  #define s2255_dev_err(dev, fmt, arg...)					\
  		dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
363
364
365
  #define dprintk(level, fmt, arg...)					\
  	do {								\
  		if (*s2255_debug >= (level)) {				\
be9ed5117   Mauro Carvalho Chehab   V4L/DVB (10298): ...
366
367
  			printk(KERN_DEBUG S2255_DRIVER_NAME		\
  				": " fmt, ##arg);			\
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
368
369
  		}							\
  	} while (0)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
370
  static struct usb_driver s2255_driver;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
371
372
373
374
375
  /* Declare static vars that will be used as parameters */
  static unsigned int vid_limit = 16;	/* Video memory limit, in Mb */
  
  /* start video number */
  static int video_nr = -1;	/* /dev/videoN, -1 for autodetect */
e42e28f9d   Sensoray Linux Development   [media] s2255drv:...
376
377
  /* Enable jpeg capture. */
  static int jpeg_enable = 1;
3f8d6f73d   Dean Anderson   V4L/DVB (8317): S...
378
  module_param(debug, int, 0644);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
379
  MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
3f8d6f73d   Dean Anderson   V4L/DVB (8317): S...
380
  module_param(vid_limit, int, 0644);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
381
  MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
3f8d6f73d   Dean Anderson   V4L/DVB (8317): S...
382
  module_param(video_nr, int, 0644);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
383
  MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
e42e28f9d   Sensoray Linux Development   [media] s2255drv:...
384
385
  module_param(jpeg_enable, int, 0644);
  MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
386
387
  
  /* USB device table */
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
388
  #define USB_SENSORAY_VID	0x1943
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
389
  static struct usb_device_id s2255_table[] = {
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
390
391
  	{USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
  	{USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
392
393
394
  	{ }			/* Terminating entry */
  };
  MODULE_DEVICE_TABLE(usb, s2255_table);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
395
  #define BUFFER_TIMEOUT msecs_to_jiffies(400)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
396
  /* image formats.  */
e42e28f9d   Sensoray Linux Development   [media] s2255drv:...
397
  /* JPEG formats must be defined last to support jpeg_enable parameter */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
  static const struct s2255_fmt formats[] = {
  	{
  		.name = "4:2:2, planar, YUV422P",
  		.fourcc = V4L2_PIX_FMT_YUV422P,
  		.depth = 16
  
  	}, {
  		.name = "4:2:2, packed, YUYV",
  		.fourcc = V4L2_PIX_FMT_YUYV,
  		.depth = 16
  
  	}, {
  		.name = "4:2:2, packed, UYVY",
  		.fourcc = V4L2_PIX_FMT_UYVY,
  		.depth = 16
  	}, {
e42e28f9d   Sensoray Linux Development   [media] s2255drv:...
414
415
416
417
  		.name = "8bpp GREY",
  		.fourcc = V4L2_PIX_FMT_GREY,
  		.depth = 8
  	}, {
14d962602   Dean Anderson   V4L/DVB (8752): s...
418
419
420
421
  		.name = "JPG",
  		.fourcc = V4L2_PIX_FMT_JPEG,
  		.depth = 24
  	}, {
d0ef8540f   Sensoray Linux Development   [media] s2255drv:...
422
423
424
  		.name = "MJPG",
  		.fourcc = V4L2_PIX_FMT_MJPEG,
  		.depth = 24
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
  	}
  };
  
  static int norm_maxw(struct video_device *vdev)
  {
  	return (vdev->current_norm & V4L2_STD_NTSC) ?
  	    LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
  }
  
  static int norm_maxh(struct video_device *vdev)
  {
  	return (vdev->current_norm & V4L2_STD_NTSC) ?
  	    (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
  }
  
  static int norm_minw(struct video_device *vdev)
  {
  	return (vdev->current_norm & V4L2_STD_NTSC) ?
  	    LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
  }
  
  static int norm_minh(struct video_device *vdev)
  {
  	return (vdev->current_norm & V4L2_STD_NTSC) ?
  	    (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
  }
3f8d6f73d   Dean Anderson   V4L/DVB (8317): S...
451
452
453
454
  /*
   * TODO: fixme: move YUV reordering to hardware
   * converts 2255 planar format to yuyv or uyvy
   */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
  static void planar422p_to_yuv_packed(const unsigned char *in,
  				     unsigned char *out,
  				     int width, int height,
  				     int fmt)
  {
  	unsigned char *pY;
  	unsigned char *pCb;
  	unsigned char *pCr;
  	unsigned long size = height * width;
  	unsigned int i;
  	pY = (unsigned char *)in;
  	pCr = (unsigned char *)in + height * width;
  	pCb = (unsigned char *)in + height * width + (height * width / 2);
  	for (i = 0; i < size * 2; i += 4) {
  		out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
  		out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
  		out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
  		out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
  	}
  	return;
  }
d45b9b8ab   Hans Verkuil   V4L/DVB (8906): v...
476
  static void s2255_reset_dsppower(struct s2255_dev *dev)
14d962602   Dean Anderson   V4L/DVB (8752): s...
477
  {
8a8cc952d   Sensoray Linux Development   [media] s2255drv:...
478
  	s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
14d962602   Dean Anderson   V4L/DVB (8752): s...
479
480
  	msleep(10);
  	s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
752eb7ae5   sensoray-dev   [media] s2255drv:...
481
482
  	msleep(600);
  	s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
14d962602   Dean Anderson   V4L/DVB (8752): s...
483
484
  	return;
  }
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
485
486
487
488
489
490
  
  /* kickstarts the firmware loading. from probe
   */
  static void s2255_timer(unsigned long user_data)
  {
  	struct s2255_fw *data = (struct s2255_fw *)user_data;
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
491
492
  	dprintk(100, "%s
  ", __func__);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
493
494
495
  	if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
  		printk(KERN_ERR "s2255: can't submit urb
  ");
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
496
497
498
  		atomic_set(&data->fw_state, S2255_FW_FAILED);
  		/* wake up anything waiting for the firmware */
  		wake_up(&data->wait_fw);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
499
500
501
  		return;
  	}
  }
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
502
503
504
505
506
507
508
509
510
511
512
513
  
  /* this loads the firmware asynchronously.
     Originally this was done synchroously in probe.
     But it is better to load it asynchronously here than block
     inside the probe function. Blocking inside probe affects boot time.
     FW loading is triggered by the timer in the probe function
  */
  static void s2255_fwchunk_complete(struct urb *urb)
  {
  	struct s2255_fw *data = urb->context;
  	struct usb_device *udev = urb->dev;
  	int len;
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
514
  	dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
515
  	if (urb->status) {
be9ed5117   Mauro Carvalho Chehab   V4L/DVB (10298): ...
516
517
  		dev_err(&udev->dev, "URB failed with status %d
  ", urb->status);
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
518
519
520
  		atomic_set(&data->fw_state, S2255_FW_FAILED);
  		/* wake up anything waiting for the firmware */
  		wake_up(&data->wait_fw);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
521
522
523
  		return;
  	}
  	if (data->fw_urb == NULL) {
be9ed5117   Mauro Carvalho Chehab   V4L/DVB (10298): ...
524
525
  		s2255_dev_err(&udev->dev, "disconnected
  ");
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
526
527
528
  		atomic_set(&data->fw_state, S2255_FW_FAILED);
  		/* wake up anything waiting for the firmware */
  		wake_up(&data->wait_fw);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
  		return;
  	}
  #define CHUNK_SIZE 512
  	/* all USB transfers must be done with continuous kernel memory.
  	   can't allocate more than 128k in current linux kernel, so
  	   upload the firmware in chunks
  	 */
  	if (data->fw_loaded < data->fw_size) {
  		len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
  		    data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
  
  		if (len < CHUNK_SIZE)
  			memset(data->pfw_data, 0, CHUNK_SIZE);
  
  		dprintk(100, "completed len %d, loaded %d 
  ", len,
  			data->fw_loaded);
  
  		memcpy(data->pfw_data,
  		       (char *) data->fw->data + data->fw_loaded, len);
  
  		usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
  				  data->pfw_data, CHUNK_SIZE,
  				  s2255_fwchunk_complete, data);
  		if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
  			dev_err(&udev->dev, "failed submit URB
  ");
  			atomic_set(&data->fw_state, S2255_FW_FAILED);
  			/* wake up anything waiting for the firmware */
  			wake_up(&data->wait_fw);
  			return;
  		}
  		data->fw_loaded += len;
  	} else {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
563
  		atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
564
565
  		dprintk(100, "%s: firmware upload complete
  ", __func__);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
566
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
567
568
569
  	return;
  
  }
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
570
  static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
571
  {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
572
  	struct s2255_dmaqueue *dma_q = &channel->vidq;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
573
  	struct s2255_buffer *buf;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
574
  	struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
575
576
  	unsigned long flags = 0;
  	int rc = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
577
  	spin_lock_irqsave(&dev->slock, flags);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
578
579
580
581
582
583
584
585
  	if (list_empty(&dma_q->active)) {
  		dprintk(1, "No active queue to serve
  ");
  		rc = -1;
  		goto unlock;
  	}
  	buf = list_entry(dma_q->active.next,
  			 struct s2255_buffer, vb.queue);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
586
587
  	list_del(&buf->vb.queue);
  	do_gettimeofday(&buf->vb.ts);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
588
  	s2255_fillbuff(channel, buf, jpgsize);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
589
  	wake_up(&buf->vb.done);
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
590
591
  	dprintk(2, "%s: [buf/i] [%p/%d]
  ", __func__, buf, buf->vb.i);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
592
593
  unlock:
  	spin_unlock_irqrestore(&dev->slock, flags);
f27709792   Julia Lawall   V4L/DVB: drivers/...
594
  	return rc;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
595
  }
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
596
597
598
  static const struct s2255_fmt *format_by_fourcc(int fourcc)
  {
  	unsigned int i;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
599
600
601
  	for (i = 0; i < ARRAY_SIZE(formats); i++) {
  		if (-1 == formats[i].fourcc)
  			continue;
e42e28f9d   Sensoray Linux Development   [media] s2255drv:...
602
603
604
  	if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
  			     (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
  	    continue;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
605
606
607
608
609
  		if (formats[i].fourcc == fourcc)
  			return formats + i;
  	}
  	return NULL;
  }
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
610
611
612
613
614
615
616
617
  /* video buffer vmalloc implementation based partly on VIVI driver which is
   *          Copyright (c) 2006 by
   *                  Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
   *                  Ted Walther <ted--a.t--enumera.com>
   *                  John Sokol <sokol--a.t--videotechnology.com>
   *                  http://v4l.videotechnology.com/
   *
   */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
618
619
  static void s2255_fillbuff(struct s2255_channel *channel,
  			   struct s2255_buffer *buf, int jpgsize)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
620
621
622
623
624
625
626
627
628
629
  {
  	int pos = 0;
  	struct timeval ts;
  	const char *tmpbuf;
  	char *vbuf = videobuf_to_vmalloc(&buf->vb);
  	unsigned long last_frame;
  	struct s2255_framei *frm;
  
  	if (!vbuf)
  		return;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
630
  	last_frame = channel->last_frame;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
631
  	if (last_frame != -1) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
632
  		frm = &channel->buffer.frame[last_frame];
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
633
  		tmpbuf =
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
634
  		    (const char *)channel->buffer.frame[last_frame].lpvbits;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
635
636
637
638
639
640
641
642
643
644
645
  		switch (buf->fmt->fourcc) {
  		case V4L2_PIX_FMT_YUYV:
  		case V4L2_PIX_FMT_UYVY:
  			planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
  						 vbuf, buf->vb.width,
  						 buf->vb.height,
  						 buf->fmt->fourcc);
  			break;
  		case V4L2_PIX_FMT_GREY:
  			memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
  			break;
14d962602   Dean Anderson   V4L/DVB (8752): s...
646
  		case V4L2_PIX_FMT_JPEG:
d0ef8540f   Sensoray Linux Development   [media] s2255drv:...
647
  		case V4L2_PIX_FMT_MJPEG:
14d962602   Dean Anderson   V4L/DVB (8752): s...
648
649
650
  			buf->vb.size = jpgsize;
  			memcpy(vbuf, tmpbuf, buf->vb.size);
  			break;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
651
652
653
654
655
656
657
658
  		case V4L2_PIX_FMT_YUV422P:
  			memcpy(vbuf, tmpbuf,
  			       buf->vb.width * buf->vb.height * 2);
  			break;
  		default:
  			printk(KERN_DEBUG "s2255: unknown format?
  ");
  		}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
659
  		channel->last_frame = -1;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
660
661
662
663
664
665
666
667
668
669
  	} else {
  		printk(KERN_ERR "s2255: =======no frame
  ");
  		return;
  
  	}
  	dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d
  ",
  		(unsigned long)vbuf, pos);
  	/* tell v4l buffer was filled */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
670
  	buf->vb.field_count = channel->frame_count * 2;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
671
672
673
674
675
676
677
678
679
680
681
682
683
684
  	do_gettimeofday(&ts);
  	buf->vb.ts = ts;
  	buf->vb.state = VIDEOBUF_DONE;
  }
  
  
  /* ------------------------------------------------------------------
     Videobuf operations
     ------------------------------------------------------------------*/
  
  static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
  			unsigned int *size)
  {
  	struct s2255_fh *fh = vq->priv_data;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
685
686
  	struct s2255_channel *channel = fh->channel;
  	*size = channel->width * channel->height * (channel->fmt->depth >> 3);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
687
688
689
  
  	if (0 == *count)
  		*count = S2255_DEF_BUFS;
dab7e3106   Andreas Bombe   V4L/DVB: V4L2: Re...
690
691
  	if (*size * *count > vid_limit * 1024 * 1024)
  		*count = (vid_limit * 1024 * 1024) / *size;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
692
693
694
695
696
697
698
699
  
  	return 0;
  }
  
  static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
  {
  	dprintk(4, "%s
  ", __func__);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
700
701
702
703
704
705
706
707
  	videobuf_vmalloc_free(&buf->vb);
  	buf->vb.state = VIDEOBUF_NEEDS_INIT;
  }
  
  static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
  			  enum v4l2_field field)
  {
  	struct s2255_fh *fh = vq->priv_data;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
708
  	struct s2255_channel *channel = fh->channel;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
709
710
  	struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
  	int rc;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
711
712
  	int w = channel->width;
  	int h = channel->height;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
713
714
  	dprintk(4, "%s, field=%d
  ", __func__, field);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
715
  	if (channel->fmt == NULL)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
716
  		return -EINVAL;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
717
718
719
720
  	if ((w < norm_minw(&channel->vdev)) ||
  	    (w > norm_maxw(&channel->vdev)) ||
  	    (h < norm_minh(&channel->vdev)) ||
  	    (h > norm_maxh(&channel->vdev))) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
721
722
723
724
  		dprintk(4, "invalid buffer prepare
  ");
  		return -EINVAL;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
725
  	buf->vb.size = w * h * (channel->fmt->depth >> 3);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
726
727
728
729
730
  	if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
  		dprintk(4, "invalid buffer prepare
  ");
  		return -EINVAL;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
731
732
733
  	buf->fmt = channel->fmt;
  	buf->vb.width = w;
  	buf->vb.height = h;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
734
  	buf->vb.field = field;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
  	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
  		rc = videobuf_iolock(vq, &buf->vb, NULL);
  		if (rc < 0)
  			goto fail;
  	}
  
  	buf->vb.state = VIDEOBUF_PREPARED;
  	return 0;
  fail:
  	free_buffer(vq, buf);
  	return rc;
  }
  
  static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
  {
  	struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
  	struct s2255_fh *fh = vq->priv_data;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
752
753
  	struct s2255_channel *channel = fh->channel;
  	struct s2255_dmaqueue *vidq = &channel->vidq;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
754
755
  	dprintk(1, "%s
  ", __func__);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
756
757
758
759
760
761
762
763
764
  	buf->vb.state = VIDEOBUF_QUEUED;
  	list_add_tail(&buf->vb.queue, &vidq->active);
  }
  
  static void buffer_release(struct videobuf_queue *vq,
  			   struct videobuf_buffer *vb)
  {
  	struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
  	struct s2255_fh *fh = vq->priv_data;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
765
766
  	dprintk(4, "%s %d
  ", __func__, fh->channel->idx);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
767
768
769
770
771
772
773
774
775
  	free_buffer(vq, buf);
  }
  
  static struct videobuf_queue_ops s2255_video_qops = {
  	.buf_setup = buffer_setup,
  	.buf_prepare = buffer_prepare,
  	.buf_queue = buffer_queue,
  	.buf_release = buffer_release,
  };
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
776
  static int res_get(struct s2255_fh *fh)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
777
  {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
778
  	struct s2255_channel *channel = fh->channel;
a19a5cd7b   Pete Eberlein   [media] s2255drv:...
779
780
781
  	/* is it free? */
  	if (channel->resources)
  		return 0; /* no, someone else uses it */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
782
  	/* it's free, grab it */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
783
784
  	channel->resources = 1;
  	fh->resources = 1;
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
785
786
  	dprintk(1, "s2255: res: get
  ");
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
787
788
  	return 1;
  }
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
789
  static int res_locked(struct s2255_fh *fh)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
790
  {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
791
  	return fh->channel->resources;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
792
  }
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
793
794
  static int res_check(struct s2255_fh *fh)
  {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
795
  	return fh->resources;
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
796
  }
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
797
  static void res_free(struct s2255_fh *fh)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
798
  {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
799
  	struct s2255_channel *channel = fh->channel;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
800
801
  	channel->resources = 0;
  	fh->resources = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
802
803
804
  	dprintk(1, "res: put
  ");
  }
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
  static int vidioc_querymenu(struct file *file, void *priv,
  			    struct v4l2_querymenu *qmenu)
  {
  	static const char *colorfilter[] = {
  		"Off",
  		"On",
  		NULL
  	};
  	if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
  		int i;
  		const char **menu_items = colorfilter;
  		for (i = 0; i < qmenu->index && menu_items[i]; i++)
  			; /* do nothing (from v4l2-common.c) */
  		if (menu_items[i] == NULL || menu_items[i][0] == '\0')
  			return -EINVAL;
  		strlcpy(qmenu->name, menu_items[qmenu->index],
  			sizeof(qmenu->name));
  		return 0;
  	}
  	return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
  }
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
826
827
828
829
830
831
832
  static int vidioc_querycap(struct file *file, void *priv,
  			   struct v4l2_capability *cap)
  {
  	struct s2255_fh *fh = file->private_data;
  	struct s2255_dev *dev = fh->dev;
  	strlcpy(cap->driver, "s2255", sizeof(cap->driver));
  	strlcpy(cap->card, "s2255", sizeof(cap->card));
e22ed887e   Thierry MERLE   V4L/DVB (10309): ...
833
  	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
834
835
836
837
838
839
840
841
842
843
844
845
846
  	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
  	return 0;
  }
  
  static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
  			       struct v4l2_fmtdesc *f)
  {
  	int index = 0;
  	if (f)
  		index = f->index;
  
  	if (index >= ARRAY_SIZE(formats))
  		return -EINVAL;
e42e28f9d   Sensoray Linux Development   [media] s2255drv:...
847
848
849
      if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
  			 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
  	return -EINVAL;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
850
851
852
853
854
855
856
857
858
859
860
  	dprintk(4, "name %s
  ", formats[index].name);
  	strlcpy(f->description, formats[index].name, sizeof(f->description));
  	f->pixelformat = formats[index].fourcc;
  	return 0;
  }
  
  static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
  			    struct v4l2_format *f)
  {
  	struct s2255_fh *fh = priv;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
861
  	struct s2255_channel *channel = fh->channel;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
862

fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
863
864
  	f->fmt.pix.width = channel->width;
  	f->fmt.pix.height = channel->height;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
865
  	f->fmt.pix.field = fh->vb_vidq.field;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
866
867
  	f->fmt.pix.pixelformat = channel->fmt->fourcc;
  	f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
868
  	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
3f8d6f73d   Dean Anderson   V4L/DVB (8317): S...
869
  	return 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
870
871
872
873
874
875
876
877
878
  }
  
  static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
  			      struct v4l2_format *f)
  {
  	const struct s2255_fmt *fmt;
  	enum v4l2_field field;
  	int  b_any_field = 0;
  	struct s2255_fh *fh = priv;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
879
  	struct s2255_channel *channel = fh->channel;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
880
  	int is_ntsc;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
881
  	is_ntsc =
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
882
  		(channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
883
884
885
886
887
888
889
890
891
  
  	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
  
  	if (fmt == NULL)
  		return -EINVAL;
  
  	field = f->fmt.pix.field;
  	if (field == V4L2_FIELD_ANY)
  		b_any_field = 1;
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
892
893
894
  	dprintk(50, "%s NTSC: %d suggested width: %d, height: %d
  ",
  		__func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
  	if (is_ntsc) {
  		/* NTSC */
  		if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
  			f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
  			if (b_any_field) {
  				field = V4L2_FIELD_SEQ_TB;
  			} else if (!((field == V4L2_FIELD_INTERLACED) ||
  				      (field == V4L2_FIELD_SEQ_TB) ||
  				      (field == V4L2_FIELD_INTERLACED_TB))) {
  				dprintk(1, "unsupported field setting
  ");
  				return -EINVAL;
  			}
  		} else {
  			f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
  			if (b_any_field) {
  				field = V4L2_FIELD_TOP;
  			} else if (!((field == V4L2_FIELD_TOP) ||
  				      (field == V4L2_FIELD_BOTTOM))) {
  				dprintk(1, "unsupported field setting
  ");
  				return -EINVAL;
  			}
  
  		}
  		if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
  			f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
  		else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
  			f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
  		else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
  			f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
  		else
  			f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
  	} else {
  		/* PAL */
  		if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
  			f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
  			if (b_any_field) {
  				field = V4L2_FIELD_SEQ_TB;
  			} else if (!((field == V4L2_FIELD_INTERLACED) ||
  				      (field == V4L2_FIELD_SEQ_TB) ||
  				      (field == V4L2_FIELD_INTERLACED_TB))) {
  				dprintk(1, "unsupported field setting
  ");
  				return -EINVAL;
  			}
  		} else {
  			f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
  			if (b_any_field) {
  				field = V4L2_FIELD_TOP;
  			} else if (!((field == V4L2_FIELD_TOP) ||
  				     (field == V4L2_FIELD_BOTTOM))) {
  				dprintk(1, "unsupported field setting
  ");
  				return -EINVAL;
  			}
  		}
  		if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
953
954
955
  			f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
  			field = V4L2_FIELD_SEQ_TB;
  		} else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
956
957
958
  			f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
  			field = V4L2_FIELD_TOP;
  		} else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
959
960
961
  			f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
  			field = V4L2_FIELD_TOP;
  		} else {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
962
963
964
965
  			f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
  			field = V4L2_FIELD_TOP;
  		}
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
966
967
968
  	f->fmt.pix.field = field;
  	f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
  	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
969
970
971
  	dprintk(50, "%s: set width %d height %d field %d
  ", __func__,
  		f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
972
973
974
975
976
977
978
  	return 0;
  }
  
  static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
  			    struct v4l2_format *f)
  {
  	struct s2255_fh *fh = priv;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
979
  	struct s2255_channel *channel = fh->channel;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
980
981
  	const struct s2255_fmt *fmt;
  	struct videobuf_queue *q = &fh->vb_vidq;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
982
  	struct s2255_mode mode;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
983
984
985
986
987
988
  	int ret;
  	int norm;
  
  	ret = vidioc_try_fmt_vid_cap(file, fh, f);
  
  	if (ret < 0)
3f8d6f73d   Dean Anderson   V4L/DVB (8317): S...
989
  		return ret;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
  
  	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
  
  	if (fmt == NULL)
  		return -EINVAL;
  
  	mutex_lock(&q->vb_lock);
  
  	if (videobuf_queue_is_busy(&fh->vb_vidq)) {
  		dprintk(1, "queue busy
  ");
  		ret = -EBUSY;
  		goto out_s_fmt;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1004
  	if (res_locked(fh)) {
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1005
1006
  		dprintk(1, "%s: channel busy
  ", __func__);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1007
1008
1009
  		ret = -EBUSY;
  		goto out_s_fmt;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1010
1011
1012
1013
  	mode = channel->mode;
  	channel->fmt = fmt;
  	channel->width = f->fmt.pix.width;
  	channel->height = f->fmt.pix.height;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1014
1015
  	fh->vb_vidq.field = f->fmt.pix.field;
  	fh->type = f->type;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1016
1017
1018
1019
  	norm = norm_minw(&channel->vdev);
  	if (channel->width > norm_minw(&channel->vdev)) {
  		if (channel->height > norm_minh(&channel->vdev)) {
  			if (channel->cap_parm.capturemode &
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1020
  			    V4L2_MODE_HIGHQUALITY)
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1021
  				mode.scale = SCALE_4CIFSI;
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1022
  			else
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1023
  				mode.scale = SCALE_4CIFS;
7d8535329   Dean Anderson   V4L/DVB (11851): ...
1024
  		} else
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1025
  			mode.scale = SCALE_2CIFS;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1026
1027
  
  	} else {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1028
  		mode.scale = SCALE_1CIFS;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1029
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1030
  	/* color mode */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1031
  	switch (channel->fmt->fourcc) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1032
  	case V4L2_PIX_FMT_GREY:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1033
1034
  		mode.color &= ~MASK_COLOR;
  		mode.color |= COLOR_Y8;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1035
  		break;
14d962602   Dean Anderson   V4L/DVB (8752): s...
1036
  	case V4L2_PIX_FMT_JPEG:
d0ef8540f   Sensoray Linux Development   [media] s2255drv:...
1037
  	case V4L2_PIX_FMT_MJPEG:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1038
1039
1040
  		mode.color &= ~MASK_COLOR;
  		mode.color |= COLOR_JPG;
  		mode.color |= (channel->jc.quality << 8);
14d962602   Dean Anderson   V4L/DVB (8752): s...
1041
  		break;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1042
  	case V4L2_PIX_FMT_YUV422P:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1043
1044
  		mode.color &= ~MASK_COLOR;
  		mode.color |= COLOR_YUVPL;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1045
1046
1047
1048
  		break;
  	case V4L2_PIX_FMT_YUYV:
  	case V4L2_PIX_FMT_UYVY:
  	default:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1049
1050
  		mode.color &= ~MASK_COLOR;
  		mode.color |= COLOR_YUVPK;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1051
1052
  		break;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1053
1054
1055
1056
1057
1058
1059
1060
  	if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
  		mode.restart = 1;
  	else if (mode.scale != channel->mode.scale)
  		mode.restart = 1;
  	else if (mode.format != channel->mode.format)
  		mode.restart = 1;
  	channel->mode = mode;
  	(void) s2255_set_mode(channel, &mode);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
  	ret = 0;
  out_s_fmt:
  	mutex_unlock(&q->vb_lock);
  	return ret;
  }
  
  static int vidioc_reqbufs(struct file *file, void *priv,
  			  struct v4l2_requestbuffers *p)
  {
  	int rc;
  	struct s2255_fh *fh = priv;
  	rc = videobuf_reqbufs(&fh->vb_vidq, p);
  	return rc;
  }
  
  static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
  {
  	int rc;
  	struct s2255_fh *fh = priv;
  	rc = videobuf_querybuf(&fh->vb_vidq, p);
  	return rc;
  }
  
  static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
  {
  	int rc;
  	struct s2255_fh *fh = priv;
  	rc = videobuf_qbuf(&fh->vb_vidq, p);
  	return rc;
  }
  
  static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
  {
  	int rc;
  	struct s2255_fh *fh = priv;
  	rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
  	return rc;
  }
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
  /* write to the configuration pipe, synchronously */
  static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
  			      int size)
  {
  	int pipe;
  	int done;
  	long retval = -1;
  	if (udev) {
  		pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
  		retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
  	}
  	return retval;
  }
  
  static u32 get_transfer_size(struct s2255_mode *mode)
  {
  	int linesPerFrame = LINE_SZ_DEF;
  	int pixelsPerLine = NUM_LINES_DEF;
  	u32 outImageSize;
  	u32 usbInSize;
  	unsigned int mask_mult;
  
  	if (mode == NULL)
  		return 0;
  
  	if (mode->format == FORMAT_NTSC) {
  		switch (mode->scale) {
  		case SCALE_4CIFS:
7d8535329   Dean Anderson   V4L/DVB (11851): ...
1127
  		case SCALE_4CIFSI:
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
  			linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
  			pixelsPerLine = LINE_SZ_4CIFS_NTSC;
  			break;
  		case SCALE_2CIFS:
  			linesPerFrame = NUM_LINES_2CIFS_NTSC;
  			pixelsPerLine = LINE_SZ_2CIFS_NTSC;
  			break;
  		case SCALE_1CIFS:
  			linesPerFrame = NUM_LINES_1CIFS_NTSC;
  			pixelsPerLine = LINE_SZ_1CIFS_NTSC;
  			break;
  		default:
  			break;
  		}
  	} else if (mode->format == FORMAT_PAL) {
  		switch (mode->scale) {
  		case SCALE_4CIFS:
7d8535329   Dean Anderson   V4L/DVB (11851): ...
1145
  		case SCALE_4CIFSI:
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
  			linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
  			pixelsPerLine = LINE_SZ_4CIFS_PAL;
  			break;
  		case SCALE_2CIFS:
  			linesPerFrame = NUM_LINES_2CIFS_PAL;
  			pixelsPerLine = LINE_SZ_2CIFS_PAL;
  			break;
  		case SCALE_1CIFS:
  			linesPerFrame = NUM_LINES_1CIFS_PAL;
  			pixelsPerLine = LINE_SZ_1CIFS_PAL;
  			break;
  		default:
  			break;
  		}
  	}
  	outImageSize = linesPerFrame * pixelsPerLine;
14d962602   Dean Anderson   V4L/DVB (8752): s...
1162
  	if ((mode->color & MASK_COLOR) != COLOR_Y8) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
  		/* 2 bytes/pixel if not monochrome */
  		outImageSize *= 2;
  	}
  
  	/* total bytes to send including prefix and 4K padding;
  	   must be a multiple of USB_READ_SIZE */
  	usbInSize = outImageSize + PREFIX_SIZE;	/* always send prefix */
  	mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
  	/* if size not a multiple of USB_READ_SIZE */
  	if (usbInSize & ~mask_mult)
  		usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
  	return usbInSize;
  }
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1176
  static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1177
1178
1179
1180
  {
  	struct device *dev = &sdev->udev->dev;
  	dev_info(dev, "------------------------------------------------
  ");
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1181
1182
1183
1184
1185
1186
  	dev_info(dev, "format: %d
  scale %d
  ", mode->format, mode->scale);
  	dev_info(dev, "fdec: %d
  color %d
  ", mode->fdec, mode->color);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1187
1188
  	dev_info(dev, "bright: 0x%x
  ", mode->bright);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
  	dev_info(dev, "------------------------------------------------
  ");
  }
  
  /*
   * set mode is the function which controls the DSP.
   * the restart parameter in struct s2255_mode should be set whenever
   * the image size could change via color format, video system or image
   * size.
   * When the restart parameter is set, we sleep for ONE frame to allow the
   * DSP time to get the new frame
   */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1201
  static int s2255_set_mode(struct s2255_channel *channel,
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1202
1203
1204
  			  struct s2255_mode *mode)
  {
  	int res;
3fa006052   Dean Anderson   V4L/DVB: s2255drv...
1205
  	__le32 *buffer;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1206
  	unsigned long chn_rev;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1207
  	struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1208
1209
1210
  	chn_rev = G_chnmap[channel->idx];
  	dprintk(3, "%s channel: %d
  ", __func__, channel->idx);
22b88d48a   Dean Anderson   V4L/DVB (8845): s...
1211
  	/* if JPEG, set the quality */
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1212
1213
1214
1215
  	if ((mode->color & MASK_COLOR) == COLOR_JPG) {
  		mode->color &= ~MASK_COLOR;
  		mode->color |= COLOR_JPG;
  		mode->color &= ~MASK_JPG_QUALITY;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1216
  		mode->color |= (channel->jc.quality << 8);
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1217
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1218
  	/* save the mode */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1219
1220
1221
1222
  	channel->mode = *mode;
  	channel->req_image_size = get_transfer_size(mode);
  	dprintk(1, "%s: reqsize %ld
  ", __func__, channel->req_image_size);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1223
1224
1225
1226
1227
1228
  	buffer = kzalloc(512, GFP_KERNEL);
  	if (buffer == NULL) {
  		dev_err(&dev->udev->dev, "out of mem
  ");
  		return -ENOMEM;
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1229
1230
  	/* set the mode */
  	buffer[0] = IN_DATA_TOKEN;
3fa006052   Dean Anderson   V4L/DVB: s2255drv...
1231
  	buffer[1] = (__le32) cpu_to_le32(chn_rev);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1232
  	buffer[2] = CMD_SET_MODE;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1233
1234
  	memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
  	channel->setmode_ready = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1235
1236
  	res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
  	if (debug)
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1237
  		s2255_print_cfg(dev, mode);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1238
  	kfree(buffer);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1239
  	/* wait at least 3 frames before continuing */
14d962602   Dean Anderson   V4L/DVB (8752): s...
1240
  	if (mode->restart) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1241
1242
  		wait_event_timeout(channel->wait_setmode,
  				   (channel->setmode_ready != 0),
14d962602   Dean Anderson   V4L/DVB (8752): s...
1243
  				   msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1244
  		if (channel->setmode_ready != 1) {
14d962602   Dean Anderson   V4L/DVB (8752): s...
1245
1246
1247
1248
1249
  			printk(KERN_DEBUG "s2255: no set mode response
  ");
  			res = -EFAULT;
  		}
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1250
  	/* clear the restart flag */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1251
  	channel->mode.restart = 0;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1252
1253
  	dprintk(1, "%s chn %d, result: %d
  ", __func__, channel->idx, res);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1254
1255
  	return res;
  }
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1256
  static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1257
1258
  {
  	int res;
3fa006052   Dean Anderson   V4L/DVB: s2255drv...
1259
  	__le32 *buffer;
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1260
  	u32 chn_rev;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1261
  	struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1262
1263
1264
  	chn_rev = G_chnmap[channel->idx];
  	dprintk(4, "%s chan %d
  ", __func__, channel->idx);
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1265
1266
1267
1268
  	buffer = kzalloc(512, GFP_KERNEL);
  	if (buffer == NULL) {
  		dev_err(&dev->udev->dev, "out of mem
  ");
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1269
1270
1271
1272
  		return -ENOMEM;
  	}
  	/* form the get vid status command */
  	buffer[0] = IN_DATA_TOKEN;
3fa006052   Dean Anderson   V4L/DVB: s2255drv...
1273
  	buffer[1] = (__le32) cpu_to_le32(chn_rev);
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1274
1275
  	buffer[2] = CMD_STATUS;
  	*pstatus = 0;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1276
  	channel->vidstatus_ready = 0;
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1277
1278
  	res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
  	kfree(buffer);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1279
1280
  	wait_event_timeout(channel->wait_vidstatus,
  			   (channel->vidstatus_ready != 0),
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1281
  			   msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1282
  	if (channel->vidstatus_ready != 1) {
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1283
1284
1285
1286
  		printk(KERN_DEBUG "s2255: no vidstatus response
  ");
  		res = -EFAULT;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1287
  	*pstatus = channel->vidstatus;
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1288
1289
  	dprintk(4, "%s, vid status %d
  ", __func__, *pstatus);
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1290
1291
  	return res;
  }
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1292
1293
1294
1295
1296
  static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
  {
  	int res;
  	struct s2255_fh *fh = priv;
  	struct s2255_dev *dev = fh->dev;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1297
  	struct s2255_channel *channel = fh->channel;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
  	int j;
  	dprintk(4, "%s
  ", __func__);
  	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  		dev_err(&dev->udev->dev, "invalid fh type0
  ");
  		return -EINVAL;
  	}
  	if (i != fh->type) {
  		dev_err(&dev->udev->dev, "invalid fh type1
  ");
  		return -EINVAL;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1311
  	if (!res_get(fh)) {
be9ed5117   Mauro Carvalho Chehab   V4L/DVB (10298): ...
1312
1313
  		s2255_dev_err(&dev->udev->dev, "stream busy
  ");
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1314
1315
  		return -EBUSY;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1316
1317
1318
1319
  	channel->last_frame = -1;
  	channel->bad_payload = 0;
  	channel->cur_frame = 0;
  	channel->frame_count = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1320
  	for (j = 0; j < SYS_FRAMES; j++) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1321
1322
  		channel->buffer.frame[j].ulState = S2255_READ_IDLE;
  		channel->buffer.frame[j].cur_size = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1323
1324
1325
  	}
  	res = videobuf_streamon(&fh->vb_vidq);
  	if (res == 0) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1326
1327
1328
1329
  		s2255_start_acquire(channel);
  		channel->b_acquire = 1;
  	} else
  		res_free(fh);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1330
1331
1332
1333
1334
  	return res;
  }
  
  static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
  {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1335
  	struct s2255_fh *fh = priv;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1336
1337
  	dprintk(4, "%s
  , channel: %d", __func__, fh->channel->idx);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
  	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  		printk(KERN_ERR "invalid fh type0
  ");
  		return -EINVAL;
  	}
  	if (i != fh->type) {
  		printk(KERN_ERR "invalid type i
  ");
  		return -EINVAL;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1348
  	s2255_stop_acquire(fh->channel);
b7732a32a   Dean Anderson   V4L/DVB (11392): ...
1349
  	videobuf_streamoff(&fh->vb_vidq);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1350
  	res_free(fh);
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
1351
  	return 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1352
1353
1354
1355
1356
  }
  
  static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
  {
  	struct s2255_fh *fh = priv;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1357
  	struct s2255_mode mode;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1358
1359
  	struct videobuf_queue *q = &fh->vb_vidq;
  	int ret = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1360
1361
1362
1363
1364
1365
1366
  	mutex_lock(&q->vb_lock);
  	if (videobuf_queue_is_busy(q)) {
  		dprintk(1, "queue busy
  ");
  		ret = -EBUSY;
  		goto out_s_std;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1367
  	if (res_locked(fh)) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1368
1369
1370
1371
1372
  		dprintk(1, "can't change standard after started
  ");
  		ret = -EBUSY;
  		goto out_s_std;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1373
  	mode = fh->channel->mode;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1374
  	if (*i & V4L2_STD_NTSC) {
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1375
1376
1377
  		dprintk(4, "%s NTSC
  ", __func__);
  		/* if changing format, reset frame decimation/intervals */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1378
1379
1380
1381
  		if (mode.format != FORMAT_NTSC) {
  			mode.restart = 1;
  			mode.format = FORMAT_NTSC;
  			mode.fdec = FDEC_1;
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1382
  		}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1383
  	} else if (*i & V4L2_STD_PAL) {
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1384
1385
  		dprintk(4, "%s PAL
  ", __func__);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1386
1387
1388
1389
  		if (mode.format != FORMAT_PAL) {
  			mode.restart = 1;
  			mode.format = FORMAT_PAL;
  			mode.fdec = FDEC_1;
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1390
  		}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1391
1392
1393
  	} else {
  		ret = -EINVAL;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1394
1395
  	if (mode.restart)
  		s2255_set_mode(fh->channel, &mode);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
  out_s_std:
  	mutex_unlock(&q->vb_lock);
  	return ret;
  }
  
  /* Sensoray 2255 is a multiple channel capture device.
     It does not have a "crossbar" of inputs.
     We use one V4L device per channel. The user must
     be aware that certain combinations are not allowed.
     For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
     at once in color(you can do full fps on 4 channels with greyscale.
  */
  static int vidioc_enum_input(struct file *file, void *priv,
  			     struct v4l2_input *inp)
  {
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1411
1412
  	struct s2255_fh *fh = priv;
  	struct s2255_dev *dev = fh->dev;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1413
  	struct s2255_channel *channel = fh->channel;
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1414
  	u32 status = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1415
1416
  	if (inp->index != 0)
  		return -EINVAL;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1417
1418
  	inp->type = V4L2_INPUT_TYPE_CAMERA;
  	inp->std = S2255_NORMS;
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1419
1420
1421
  	inp->status = 0;
  	if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
  		int rc;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1422
  		rc = s2255_cmd_status(fh->channel, &status);
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
1423
1424
1425
1426
1427
1428
  		dprintk(4, "s2255_cmd_status rc: %d status %x
  ", rc, status);
  		if (rc == 0)
  			inp->status =  (status & 0x01) ? 0
  				: V4L2_IN_ST_NO_SIGNAL;
  	}
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1429
1430
1431
1432
1433
1434
  	switch (dev->pid) {
  	case 0x2255:
  	default:
  		strlcpy(inp->name, "Composite", sizeof(inp->name));
  		break;
  	case 0x2257:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1435
  		strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1436
1437
1438
  			sizeof(inp->name));
  		break;
  	}
3f8d6f73d   Dean Anderson   V4L/DVB (8317): S...
1439
  	return 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
  }
  
  static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
  {
  	*i = 0;
  	return 0;
  }
  static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
  {
  	if (i > 0)
  		return -EINVAL;
  	return 0;
  }
  
  /* --- controls ---------------------------------------------- */
  static int vidioc_queryctrl(struct file *file, void *priv,
  			    struct v4l2_queryctrl *qc)
  {
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1458
  	struct s2255_fh *fh = priv;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1459
  	struct s2255_channel *channel = fh->channel;
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1460
  	struct s2255_dev *dev = fh->dev;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
  	switch (qc->id) {
  	case V4L2_CID_BRIGHTNESS:
  		v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
  		break;
  	case V4L2_CID_CONTRAST:
  		v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
  		break;
  	case V4L2_CID_SATURATION:
  		v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
  		break;
  	case V4L2_CID_HUE:
  		v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
  		break;
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1474
1475
1476
  	case V4L2_CID_PRIVATE_COLORFILTER:
  		if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
  			return -EINVAL;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1477
  		if ((dev->pid == 0x2257) && (channel->idx > 1))
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1478
1479
1480
1481
1482
1483
1484
1485
1486
  			return -EINVAL;
  		strlcpy(qc->name, "Color Filter", sizeof(qc->name));
  		qc->type = V4L2_CTRL_TYPE_MENU;
  		qc->minimum = 0;
  		qc->maximum = 1;
  		qc->step = 1;
  		qc->default_value = 1;
  		qc->flags = 0;
  		break;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1487
1488
1489
1490
1491
1492
  	default:
  		return -EINVAL;
  	}
  	dprintk(4, "%s, id %d
  ", __func__, qc->id);
  	return 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1493
1494
1495
1496
1497
  }
  
  static int vidioc_g_ctrl(struct file *file, void *priv,
  			 struct v4l2_control *ctrl)
  {
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1498
  	struct s2255_fh *fh = priv;
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1499
  	struct s2255_dev *dev = fh->dev;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1500
  	struct s2255_channel *channel = fh->channel;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1501
1502
  	switch (ctrl->id) {
  	case V4L2_CID_BRIGHTNESS:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1503
  		ctrl->value = channel->mode.bright;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1504
1505
  		break;
  	case V4L2_CID_CONTRAST:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1506
  		ctrl->value = channel->mode.contrast;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1507
1508
  		break;
  	case V4L2_CID_SATURATION:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1509
  		ctrl->value = channel->mode.saturation;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1510
1511
  		break;
  	case V4L2_CID_HUE:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1512
  		ctrl->value = channel->mode.hue;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1513
  		break;
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1514
1515
1516
  	case V4L2_CID_PRIVATE_COLORFILTER:
  		if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
  			return -EINVAL;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1517
  		if ((dev->pid == 0x2257) && (channel->idx > 1))
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1518
  			return -EINVAL;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1519
  		ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1520
  		break;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1521
1522
1523
1524
1525
1526
  	default:
  		return -EINVAL;
  	}
  	dprintk(4, "%s, id %d val %d
  ", __func__, ctrl->id, ctrl->value);
  	return 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1527
1528
1529
1530
1531
  }
  
  static int vidioc_s_ctrl(struct file *file, void *priv,
  			 struct v4l2_control *ctrl)
  {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1532
  	struct s2255_fh *fh = priv;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1533
1534
1535
1536
  	struct s2255_channel *channel = fh->channel;
  	struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
  	struct s2255_mode mode;
  	mode = channel->mode;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1537
1538
1539
1540
1541
  	dprintk(4, "%s
  ", __func__);
  	/* update the mode to the corresponding value */
  	switch (ctrl->id) {
  	case V4L2_CID_BRIGHTNESS:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1542
  		mode.bright = ctrl->value;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1543
1544
  		break;
  	case V4L2_CID_CONTRAST:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1545
  		mode.contrast = ctrl->value;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1546
1547
  		break;
  	case V4L2_CID_HUE:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1548
  		mode.hue = ctrl->value;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1549
1550
  		break;
  	case V4L2_CID_SATURATION:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1551
  		mode.saturation = ctrl->value;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1552
  		break;
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1553
1554
1555
  	case V4L2_CID_PRIVATE_COLORFILTER:
  		if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
  			return -EINVAL;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1556
  		if ((dev->pid == 0x2257) && (channel->idx > 1))
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1557
  			return -EINVAL;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1558
1559
  		mode.color &= ~MASK_INPUT_TYPE;
  		mode.color |= ((ctrl->value ? 0 : 1) << 16);
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1560
  		break;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1561
1562
  	default:
  		return -EINVAL;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1563
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1564
  	mode.restart = 0;
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1565
1566
1567
1568
  	/* set mode here.  Note: stream does not need restarted.
  	   some V4L programs restart stream unnecessarily
  	   after a s_crtl.
  	*/
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1569
  	s2255_set_mode(fh->channel, &mode);
2e70db9a4   Dean Anderson   V4L/DVB: s2255drv...
1570
  	return 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1571
  }
22b88d48a   Dean Anderson   V4L/DVB (8845): s...
1572
1573
1574
1575
  static int vidioc_g_jpegcomp(struct file *file, void *priv,
  			 struct v4l2_jpegcompression *jc)
  {
  	struct s2255_fh *fh = priv;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1576
1577
  	struct s2255_channel *channel = fh->channel;
  	*jc = channel->jc;
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1578
1579
  	dprintk(2, "%s: quality %d
  ", __func__, jc->quality);
22b88d48a   Dean Anderson   V4L/DVB (8845): s...
1580
1581
1582
1583
1584
1585
1586
  	return 0;
  }
  
  static int vidioc_s_jpegcomp(struct file *file, void *priv,
  			 struct v4l2_jpegcompression *jc)
  {
  	struct s2255_fh *fh = priv;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1587
  	struct s2255_channel *channel = fh->channel;
22b88d48a   Dean Anderson   V4L/DVB (8845): s...
1588
1589
  	if (jc->quality < 0 || jc->quality > 100)
  		return -EINVAL;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1590
  	channel->jc.quality = jc->quality;
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1591
1592
  	dprintk(2, "%s: quality %d
  ", __func__, jc->quality);
22b88d48a   Dean Anderson   V4L/DVB (8845): s...
1593
1594
  	return 0;
  }
7d8535329   Dean Anderson   V4L/DVB (11851): ...
1595
1596
1597
1598
1599
  
  static int vidioc_g_parm(struct file *file, void *priv,
  			 struct v4l2_streamparm *sp)
  {
  	struct s2255_fh *fh = priv;
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1600
  	__u32 def_num, def_dem;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1601
  	struct s2255_channel *channel = fh->channel;
7d8535329   Dean Anderson   V4L/DVB (11851): ...
1602
1603
  	if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
  		return -EINVAL;
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1604
1605
  	memset(sp, 0, sizeof(struct v4l2_streamparm));
  	sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1606
1607
1608
  	sp->parm.capture.capturemode = channel->cap_parm.capturemode;
  	def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
  	def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1609
  	sp->parm.capture.timeperframe.denominator = def_dem;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1610
  	switch (channel->mode.fdec) {
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
  	default:
  	case FDEC_1:
  		sp->parm.capture.timeperframe.numerator = def_num;
  		break;
  	case FDEC_2:
  		sp->parm.capture.timeperframe.numerator = def_num * 2;
  		break;
  	case FDEC_3:
  		sp->parm.capture.timeperframe.numerator = def_num * 3;
  		break;
  	case FDEC_5:
  		sp->parm.capture.timeperframe.numerator = def_num * 5;
  		break;
  	}
  	dprintk(4, "%s capture mode, %d timeperframe %d/%d
  ", __func__,
  		sp->parm.capture.capturemode,
  		sp->parm.capture.timeperframe.numerator,
  		sp->parm.capture.timeperframe.denominator);
7d8535329   Dean Anderson   V4L/DVB (11851): ...
1630
1631
1632
1633
1634
1635
1636
  	return 0;
  }
  
  static int vidioc_s_parm(struct file *file, void *priv,
  			 struct v4l2_streamparm *sp)
  {
  	struct s2255_fh *fh = priv;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1637
1638
  	struct s2255_channel *channel = fh->channel;
  	struct s2255_mode mode;
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1639
1640
  	int fdec = FDEC_1;
  	__u32 def_num, def_dem;
7d8535329   Dean Anderson   V4L/DVB (11851): ...
1641
1642
  	if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
  		return -EINVAL;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1643
  	mode = channel->mode;
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1644
  	/* high quality capture mode requires a stream restart */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1645
1646
  	if (channel->cap_parm.capturemode
  	    != sp->parm.capture.capturemode && res_locked(fh))
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1647
  		return -EBUSY;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1648
1649
  	def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
  	def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
  	if (def_dem != sp->parm.capture.timeperframe.denominator)
  		sp->parm.capture.timeperframe.numerator = def_num;
  	else if (sp->parm.capture.timeperframe.numerator <= def_num)
  		sp->parm.capture.timeperframe.numerator = def_num;
  	else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
  		sp->parm.capture.timeperframe.numerator = def_num * 2;
  		fdec = FDEC_2;
  	} else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
  		sp->parm.capture.timeperframe.numerator = def_num * 3;
  		fdec = FDEC_3;
  	} else {
  		sp->parm.capture.timeperframe.numerator = def_num * 5;
  		fdec = FDEC_5;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1664
  	mode.fdec = fdec;
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1665
  	sp->parm.capture.timeperframe.denominator = def_dem;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1666
  	s2255_set_mode(channel, &mode);
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1667
1668
1669
1670
1671
1672
1673
1674
  	dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d
  ",
  		__func__,
  		sp->parm.capture.capturemode,
  		sp->parm.capture.timeperframe.numerator,
  		sp->parm.capture.timeperframe.denominator, fdec);
  	return 0;
  }
7d8535329   Dean Anderson   V4L/DVB (11851): ...
1675

e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
  static int vidioc_enum_frameintervals(struct file *file, void *priv,
  			    struct v4l2_frmivalenum *fe)
  {
  	int is_ntsc = 0;
  #define NUM_FRAME_ENUMS 4
  	int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
  	if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
  		return -EINVAL;
  	switch (fe->width) {
  	case 640:
  		if (fe->height != 240 && fe->height != 480)
  			return -EINVAL;
  		is_ntsc = 1;
  		break;
  	case 320:
  		if (fe->height != 240)
  			return -EINVAL;
  		is_ntsc = 1;
  		break;
  	case 704:
  		if (fe->height != 288 && fe->height != 576)
  			return -EINVAL;
  		break;
  	case 352:
  		if (fe->height != 288)
  			return -EINVAL;
  		break;
  	default:
  		return -EINVAL;
  	}
  	fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
  	fe->discrete.denominator = is_ntsc ? 30000 : 25000;
  	fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
  	dprintk(4, "%s discrete %d/%d
  ", __func__, fe->discrete.numerator,
  		fe->discrete.denominator);
7d8535329   Dean Anderson   V4L/DVB (11851): ...
1712
1713
  	return 0;
  }
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1714

bec43661b   Hans Verkuil   V4L/DVB (10135): ...
1715
  static int s2255_open(struct file *file)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1716
  {
63b0d5ad2   Laurent Pinchart   V4L/DVB (13554a):...
1717
  	struct video_device *vdev = video_devdata(file);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1718
1719
  	struct s2255_channel *channel = video_drvdata(file);
  	struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1720
  	struct s2255_fh *fh;
63b0d5ad2   Laurent Pinchart   V4L/DVB (13554a):...
1721
  	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
14d962602   Dean Anderson   V4L/DVB (8752): s...
1722
  	int state;
50462eb06   Laurent Pinchart   V4L/DVB (13555): ...
1723
1724
1725
  	dprintk(1, "s2255: open called (dev=%s)
  ",
  		video_device_node_name(vdev));
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
  	/*
  	 * open lock necessary to prevent multiple instances
  	 * of v4l-conf (or other programs) from simultaneously
  	 * reloading firmware.
  	 */
  	mutex_lock(&dev->open_lock);
  	state = atomic_read(&dev->fw_data->fw_state);
  	switch (state) {
  	case S2255_FW_DISCONNECTING:
  		mutex_unlock(&dev->open_lock);
14d962602   Dean Anderson   V4L/DVB (8752): s...
1736
  		return -ENODEV;
14d962602   Dean Anderson   V4L/DVB (8752): s...
1737
  	case S2255_FW_FAILED:
be9ed5117   Mauro Carvalho Chehab   V4L/DVB (10298): ...
1738
1739
1740
  		s2255_dev_err(&dev->udev->dev,
  			"firmware load failed. retrying.
  ");
14d962602   Dean Anderson   V4L/DVB (8752): s...
1741
  		s2255_fwload_start(dev, 1);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1742
  		wait_event_timeout(dev->fw_data->wait_fw,
14d962602   Dean Anderson   V4L/DVB (8752): s...
1743
1744
1745
1746
  				   ((atomic_read(&dev->fw_data->fw_state)
  				     == S2255_FW_SUCCESS) ||
  				    (atomic_read(&dev->fw_data->fw_state)
  				     == S2255_FW_DISCONNECTING)),
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1747
  				   msecs_to_jiffies(S2255_LOAD_TIMEOUT));
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1748
1749
  		/* state may have changed, re-read */
  		state = atomic_read(&dev->fw_data->fw_state);
14d962602   Dean Anderson   V4L/DVB (8752): s...
1750
1751
1752
  		break;
  	case S2255_FW_NOTLOADED:
  	case S2255_FW_LOADED_DSPWAIT:
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1753
1754
1755
1756
1757
  		/* give S2255_LOAD_TIMEOUT time for firmware to load in case
  		   driver loaded and then device immediately opened */
  		printk(KERN_INFO "%s waiting for firmware load
  ", __func__);
  		wait_event_timeout(dev->fw_data->wait_fw,
14d962602   Dean Anderson   V4L/DVB (8752): s...
1758
1759
1760
1761
  				   ((atomic_read(&dev->fw_data->fw_state)
  				     == S2255_FW_SUCCESS) ||
  				    (atomic_read(&dev->fw_data->fw_state)
  				     == S2255_FW_DISCONNECTING)),
eb78deecb   Dean Anderson   V4L/DVB: s2255drv...
1762
  				   msecs_to_jiffies(S2255_LOAD_TIMEOUT));
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1763
1764
  		/* state may have changed, re-read */
  		state = atomic_read(&dev->fw_data->fw_state);
14d962602   Dean Anderson   V4L/DVB (8752): s...
1765
1766
1767
1768
1769
  		break;
  	case S2255_FW_SUCCESS:
  	default:
  		break;
  	}
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1770
1771
1772
1773
1774
1775
1776
  	/* state may have changed in above switch statement */
  	switch (state) {
  	case S2255_FW_SUCCESS:
  		break;
  	case S2255_FW_FAILED:
  		printk(KERN_INFO "2255 firmware load failed.
  ");
eb78deecb   Dean Anderson   V4L/DVB: s2255drv...
1777
  		mutex_unlock(&dev->open_lock);
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1778
1779
1780
1781
  		return -ENODEV;
  	case S2255_FW_DISCONNECTING:
  		printk(KERN_INFO "%s: disconnecting
  ", __func__);
eb78deecb   Dean Anderson   V4L/DVB: s2255drv...
1782
  		mutex_unlock(&dev->open_lock);
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1783
1784
1785
1786
1787
1788
1789
  		return -ENODEV;
  	case S2255_FW_LOADED_DSPWAIT:
  	case S2255_FW_NOTLOADED:
  		printk(KERN_INFO "%s: firmware not loaded yet"
  		       "please try again later
  ",
  		       __func__);
eb78deecb   Dean Anderson   V4L/DVB: s2255drv...
1790
1791
1792
1793
1794
1795
1796
1797
  		/*
  		 * Timeout on firmware load means device unusable.
  		 * Set firmware failure state.
  		 * On next s2255_open the firmware will be reloaded.
  		 */
  		atomic_set(&dev->fw_data->fw_state,
  			   S2255_FW_FAILED);
  		mutex_unlock(&dev->open_lock);
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1798
1799
1800
1801
  		return -EAGAIN;
  	default:
  		printk(KERN_INFO "%s: unknown state
  ", __func__);
eb78deecb   Dean Anderson   V4L/DVB: s2255drv...
1802
  		mutex_unlock(&dev->open_lock);
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1803
  		return -EFAULT;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1804
  	}
eb78deecb   Dean Anderson   V4L/DVB: s2255drv...
1805
  	mutex_unlock(&dev->open_lock);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1806
1807
  	/* allocate + initialize per filehandle data */
  	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
a5ef91c9a   Dean Anderson   V4L/DVB: s2255drv...
1808
  	if (NULL == fh)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1809
  		return -ENOMEM;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1810
1811
1812
  	file->private_data = fh;
  	fh->dev = dev;
  	fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1813
1814
1815
1816
1817
1818
  	fh->channel = channel;
  	if (!channel->configured) {
  		/* configure channel to default state */
  		channel->fmt = &formats[0];
  		s2255_set_mode(channel, &channel->mode);
  		channel->configured = 1;
14d962602   Dean Anderson   V4L/DVB (8752): s...
1819
  	}
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1820
1821
  	dprintk(1, "%s: dev=%s type=%s
  ", __func__,
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1822
  		video_device_node_name(vdev), v4l2_type_names[type]);
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1823
1824
  	dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx
  ", __func__,
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1825
  		(unsigned long)fh, (unsigned long)dev,
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1826
  		(unsigned long)&channel->vidq);
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1827
1828
  	dprintk(4, "%s: list_empty active=%d
  ", __func__,
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1829
  		list_empty(&channel->vidq.active));
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1830
1831
1832
1833
  	videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
  				    NULL, &dev->slock,
  				    fh->type,
  				    V4L2_FIELD_INTERLACED,
a19a5cd7b   Pete Eberlein   [media] s2255drv:...
1834
1835
  				    sizeof(struct s2255_buffer),
  				    fh, vdev->lock);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
  	return 0;
  }
  
  
  static unsigned int s2255_poll(struct file *file,
  			       struct poll_table_struct *wait)
  {
  	struct s2255_fh *fh = file->private_data;
  	int rc;
  	dprintk(100, "%s
  ", __func__);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1847
1848
  	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
  		return POLLERR;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1849
1850
1851
  	rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
  	return rc;
  }
d62e85a09   Dean Anderson   V4L/DVB: s2255drv...
1852
  static void s2255_destroy(struct s2255_dev *dev)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1853
  {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1854
1855
  	/* board shutdown stops the read pipe if it is running */
  	s2255_board_shutdown(dev);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1856
  	/* make sure firmware still not trying to load */
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
1857
  	del_timer(&dev->timer);  /* only started in .probe and .open */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1858
  	if (dev->fw_data->fw_urb) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1859
1860
1861
1862
  		usb_kill_urb(dev->fw_data->fw_urb);
  		usb_free_urb(dev->fw_data->fw_urb);
  		dev->fw_data->fw_urb = NULL;
  	}
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
1863
1864
1865
1866
  	if (dev->fw_data->fw)
  		release_firmware(dev->fw_data->fw);
  	kfree(dev->fw_data->pfw_data);
  	kfree(dev->fw_data);
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1867
1868
1869
1870
  	/* reset the DSP so firmware can be reloaded next time */
  	s2255_reset_dsppower(dev);
  	mutex_destroy(&dev->open_lock);
  	mutex_destroy(&dev->lock);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1871
  	usb_put_dev(dev->udev);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1872
  	v4l2_device_unregister(&dev->v4l2_dev);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1873
  	dprintk(1, "%s", __func__);
b7732a32a   Dean Anderson   V4L/DVB (11392): ...
1874
  	kfree(dev);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1875
  }
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1876
  static int s2255_release(struct file *file)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1877
1878
1879
  {
  	struct s2255_fh *fh = file->private_data;
  	struct s2255_dev *dev = fh->dev;
50462eb06   Laurent Pinchart   V4L/DVB (13555): ...
1880
  	struct video_device *vdev = video_devdata(file);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1881
  	struct s2255_channel *channel = fh->channel;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1882
1883
  	if (!dev)
  		return -ENODEV;
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
1884
1885
  	/* turn off stream */
  	if (res_check(fh)) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1886
1887
  		if (channel->b_acquire)
  			s2255_stop_acquire(fh->channel);
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
1888
  		videobuf_streamoff(&fh->vb_vidq);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1889
  		res_free(fh);
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
1890
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1891
  	videobuf_mmap_free(&fh->vb_vidq);
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1892
1893
  	dprintk(1, "%s (dev=%s)
  ", __func__, video_device_node_name(vdev));
f78d92c9f   Dean Anderson   V4L/DVB (8490): s...
1894
  	kfree(fh);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
  	return 0;
  }
  
  static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
  {
  	struct s2255_fh *fh = file->private_data;
  	int ret;
  
  	if (!fh)
  		return -ENODEV;
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1905
1906
  	dprintk(4, "%s, vma=0x%08lx
  ", __func__, (unsigned long)vma);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1907
  	ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
1908
1909
  	dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d
  ", __func__,
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1910
1911
  		(unsigned long)vma->vm_start,
  		(unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1912
1913
  	return ret;
  }
bec43661b   Hans Verkuil   V4L/DVB (10135): ...
1914
  static const struct v4l2_file_operations s2255_fops_v4l = {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1915
1916
  	.owner = THIS_MODULE,
  	.open = s2255_open,
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1917
  	.release = s2255_release,
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1918
  	.poll = s2255_poll,
a19a5cd7b   Pete Eberlein   [media] s2255drv:...
1919
  	.unlocked_ioctl = video_ioctl2,	/* V4L2 ioctl handler */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1920
  	.mmap = s2255_mmap_v4l,
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1921
  };
a399810ca   Hans Verkuil   V4L/DVB (8482): v...
1922
  static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
1923
  	.vidioc_querymenu = vidioc_querymenu,
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
  	.vidioc_querycap = vidioc_querycap,
  	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
  	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
  	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
  	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
  	.vidioc_reqbufs = vidioc_reqbufs,
  	.vidioc_querybuf = vidioc_querybuf,
  	.vidioc_qbuf = vidioc_qbuf,
  	.vidioc_dqbuf = vidioc_dqbuf,
  	.vidioc_s_std = vidioc_s_std,
  	.vidioc_enum_input = vidioc_enum_input,
  	.vidioc_g_input = vidioc_g_input,
  	.vidioc_s_input = vidioc_s_input,
  	.vidioc_queryctrl = vidioc_queryctrl,
  	.vidioc_g_ctrl = vidioc_g_ctrl,
  	.vidioc_s_ctrl = vidioc_s_ctrl,
  	.vidioc_streamon = vidioc_streamon,
  	.vidioc_streamoff = vidioc_streamoff,
22b88d48a   Dean Anderson   V4L/DVB (8845): s...
1942
1943
  	.vidioc_s_jpegcomp = vidioc_s_jpegcomp,
  	.vidioc_g_jpegcomp = vidioc_g_jpegcomp,
7d8535329   Dean Anderson   V4L/DVB (11851): ...
1944
1945
  	.vidioc_s_parm = vidioc_s_parm,
  	.vidioc_g_parm = vidioc_g_parm,
e6b44bc52   Dean Anderson   V4L/DVB: s2255drv...
1946
  	.vidioc_enum_frameintervals = vidioc_enum_frameintervals,
a399810ca   Hans Verkuil   V4L/DVB (8482): v...
1947
  };
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1948
1949
  static void s2255_video_device_release(struct video_device *vdev)
  {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1950
1951
1952
1953
1954
  	struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
  	dprintk(4, "%s, chnls: %d 
  ", __func__,
  		atomic_read(&dev->num_channels));
  	if (atomic_dec_and_test(&dev->num_channels))
d62e85a09   Dean Anderson   V4L/DVB: s2255drv...
1955
  		s2255_destroy(dev);
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1956
1957
  	return;
  }
a399810ca   Hans Verkuil   V4L/DVB (8482): v...
1958
1959
  static struct video_device template = {
  	.name = "s2255v",
a399810ca   Hans Verkuil   V4L/DVB (8482): v...
1960
1961
  	.fops = &s2255_fops_v4l,
  	.ioctl_ops = &s2255_ioctl_ops,
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
1962
  	.release = s2255_video_device_release,
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1963
1964
1965
1966
1967
1968
1969
1970
1971
  	.tvnorms = S2255_NORMS,
  	.current_norm = V4L2_STD_NTSC_M,
  };
  
  static int s2255_probe_v4l(struct s2255_dev *dev)
  {
  	int ret;
  	int i;
  	int cur_nr = video_nr;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1972
  	struct s2255_channel *channel;
65c6edb30   Dean Anderson   V4L/DVB: s2255drv...
1973
1974
1975
  	ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
  	if (ret)
  		return ret;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1976
  	/* initialize all video 4 linux */
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1977
1978
  	/* register 4 video devices */
  	for (i = 0; i < MAX_CHANNELS; i++) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1979
1980
1981
  		channel = &dev->channel[i];
  		INIT_LIST_HEAD(&channel->vidq.active);
  		channel->vidq.dev = dev;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1982
  		/* register 4 video devices */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1983
  		channel->vdev = template;
a19a5cd7b   Pete Eberlein   [media] s2255drv:...
1984
  		channel->vdev.lock = &dev->lock;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1985
1986
  		channel->vdev.v4l2_dev = &dev->v4l2_dev;
  		video_set_drvdata(&channel->vdev, channel);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1987
  		if (video_nr == -1)
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1988
  			ret = video_register_device(&channel->vdev,
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1989
1990
1991
  						    VFL_TYPE_GRABBER,
  						    video_nr);
  		else
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1992
  			ret = video_register_device(&channel->vdev,
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1993
1994
  						    VFL_TYPE_GRABBER,
  						    cur_nr + i);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
1995

3a67b5cc6   Dean Anderson   V4L/DVB: s2255drv...
1996
  		if (ret) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
1997
1998
1999
  			dev_err(&dev->udev->dev,
  				"failed to register video device!
  ");
3a67b5cc6   Dean Anderson   V4L/DVB: s2255drv...
2000
  			break;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2001
  		}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2002
  		atomic_inc(&dev->num_channels);
65c6edb30   Dean Anderson   V4L/DVB: s2255drv...
2003
2004
  		v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s
  ",
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2005
  			  video_device_node_name(&channel->vdev));
3a67b5cc6   Dean Anderson   V4L/DVB: s2255drv...
2006

38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2007
  	}
64dc3c1a9   Mauro Carvalho Chehab   [media] Stop usin...
2008
2009
2010
  	printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %s
  ",
  	       S2255_VERSION);
3a67b5cc6   Dean Anderson   V4L/DVB: s2255drv...
2011
  	/* if no channels registered, return error and probe will fail*/
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2012
  	if (atomic_read(&dev->num_channels) == 0) {
65c6edb30   Dean Anderson   V4L/DVB: s2255drv...
2013
  		v4l2_device_unregister(&dev->v4l2_dev);
3a67b5cc6   Dean Anderson   V4L/DVB: s2255drv...
2014
  		return ret;
65c6edb30   Dean Anderson   V4L/DVB: s2255drv...
2015
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2016
  	if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
3a67b5cc6   Dean Anderson   V4L/DVB: s2255drv...
2017
2018
2019
  		printk(KERN_WARNING "s2255: Not all channels available.
  ");
  	return 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2020
  }
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2021
2022
2023
2024
2025
2026
  /* this function moves the usb stream read pipe data
   * into the system buffers.
   * returns 0 on success, EAGAIN if more data to process( call this
   * function again).
   *
   * Received frame structure:
14d962602   Dean Anderson   V4L/DVB (8752): s...
2027
   * bytes 0-3:  marker : 0x2255DA4AL (S2255_MARKER_FRAME)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2028
2029
2030
2031
2032
2033
   * bytes 4-7:  channel: 0-3
   * bytes 8-11: payload size:  size of the frame
   * bytes 12-payloadsize+12:  frame data
   */
  static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
  {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2034
2035
  	char *pdest;
  	u32 offset = 0;
14d962602   Dean Anderson   V4L/DVB (8752): s...
2036
  	int bframe = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2037
2038
2039
2040
2041
2042
  	char *psrc;
  	unsigned long copy_size;
  	unsigned long size;
  	s32 idx = -1;
  	struct s2255_framei *frm;
  	unsigned char *pdata;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2043
  	struct s2255_channel *channel;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2044
2045
  	dprintk(100, "buffer to user
  ");
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2046
2047
2048
  	channel = &dev->channel[dev->cc];
  	idx = channel->cur_frame;
  	frm = &channel->buffer.frame[idx];
14d962602   Dean Anderson   V4L/DVB (8752): s...
2049
2050
2051
  	if (frm->ulState == S2255_READ_IDLE) {
  		int jj;
  		unsigned int cc;
3fa006052   Dean Anderson   V4L/DVB: s2255drv...
2052
  		__le32 *pdword; /*data from dsp is little endian */
14d962602   Dean Anderson   V4L/DVB (8752): s...
2053
2054
2055
  		int payload;
  		/* search for marker codes */
  		pdata = (unsigned char *)pipe_info->transfer_buffer;
3fa006052   Dean Anderson   V4L/DVB: s2255drv...
2056
  		pdword = (__le32 *)pdata;
14d962602   Dean Anderson   V4L/DVB (8752): s...
2057
  		for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
3fa006052   Dean Anderson   V4L/DVB: s2255drv...
2058
  			switch (*pdword) {
14d962602   Dean Anderson   V4L/DVB (8752): s...
2059
  			case S2255_MARKER_FRAME:
14d962602   Dean Anderson   V4L/DVB (8752): s...
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
  				dprintk(4, "found frame marker at offset:"
  					" %d [%x %x]
  ", jj, pdata[0],
  					pdata[1]);
  				offset = jj + PREFIX_SIZE;
  				bframe = 1;
  				cc = pdword[1];
  				if (cc >= MAX_CHANNELS) {
  					printk(KERN_ERR
  					       "bad channel
  ");
  					return -EINVAL;
  				}
  				/* reverse it */
  				dev->cc = G_chnmap[cc];
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2075
  				channel = &dev->channel[dev->cc];
14d962602   Dean Anderson   V4L/DVB (8752): s...
2076
  				payload =  pdword[3];
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2077
2078
  				if (payload > channel->req_image_size) {
  					channel->bad_payload++;
14d962602   Dean Anderson   V4L/DVB (8752): s...
2079
2080
2081
  					/* discard the bad frame */
  					return -EINVAL;
  				}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2082
2083
  				channel->pkt_size = payload;
  				channel->jpg_size = pdword[4];
14d962602   Dean Anderson   V4L/DVB (8752): s...
2084
2085
  				break;
  			case S2255_MARKER_RESPONSE:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2086

14d962602   Dean Anderson   V4L/DVB (8752): s...
2087
2088
2089
2090
2091
  				pdata += DEF_USB_BLOCK;
  				jj += DEF_USB_BLOCK;
  				if (pdword[1] >= MAX_CHANNELS)
  					break;
  				cc = G_chnmap[pdword[1]];
f14a2972e   Roel Kluin   V4L/DVB (13241): ...
2092
  				if (cc >= MAX_CHANNELS)
14d962602   Dean Anderson   V4L/DVB (8752): s...
2093
  					break;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2094
  				channel = &dev->channel[cc];
14d962602   Dean Anderson   V4L/DVB (8752): s...
2095
  				switch (pdword[2]) {
abce21f40   Dean Anderson   V4L/DVB (11605): ...
2096
  				case S2255_RESPONSE_SETMODE:
14d962602   Dean Anderson   V4L/DVB (8752): s...
2097
2098
  					/* check if channel valid */
  					/* set mode ready */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2099
2100
  					channel->setmode_ready = 1;
  					wake_up(&channel->wait_setmode);
14d962602   Dean Anderson   V4L/DVB (8752): s...
2101
2102
  					dprintk(5, "setmode ready %d
  ", cc);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2103
  					break;
abce21f40   Dean Anderson   V4L/DVB (11605): ...
2104
  				case S2255_RESPONSE_FW:
14d962602   Dean Anderson   V4L/DVB (8752): s...
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
  					dev->chn_ready |= (1 << cc);
  					if ((dev->chn_ready & 0x0f) != 0x0f)
  						break;
  					/* all channels ready */
  					printk(KERN_INFO "s2255: fw loaded
  ");
  					atomic_set(&dev->fw_data->fw_state,
  						   S2255_FW_SUCCESS);
  					wake_up(&dev->fw_data->wait_fw);
  					break;
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
2115
  				case S2255_RESPONSE_STATUS:
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2116
2117
2118
  					channel->vidstatus = pdword[3];
  					channel->vidstatus_ready = 1;
  					wake_up(&channel->wait_vidstatus);
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
2119
2120
2121
2122
  					dprintk(5, "got vidstatus %x chan %d
  ",
  						pdword[3], cc);
  					break;
14d962602   Dean Anderson   V4L/DVB (8752): s...
2123
  				default:
af901ca18   André Goddard Rosa   tree-wide: fix as...
2124
2125
  					printk(KERN_INFO "s2255 unknown resp
  ");
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2126
  				}
14d962602   Dean Anderson   V4L/DVB (8752): s...
2127
  			default:
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2128
  				pdata++;
14d962602   Dean Anderson   V4L/DVB (8752): s...
2129
  				break;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2130
  			}
14d962602   Dean Anderson   V4L/DVB (8752): s...
2131
2132
2133
2134
2135
  			if (bframe)
  				break;
  		} /* for */
  		if (!bframe)
  			return -EINVAL;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2136
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2137
2138
2139
  	channel = &dev->channel[dev->cc];
  	idx = channel->cur_frame;
  	frm = &channel->buffer.frame[idx];
14d962602   Dean Anderson   V4L/DVB (8752): s...
2140
  	/* search done.  now find out if should be acquiring on this channel */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2141
  	if (!channel->b_acquire) {
14d962602   Dean Anderson   V4L/DVB (8752): s...
2142
2143
2144
  		/* we found a frame, but this channel is turned off */
  		frm->ulState = S2255_READ_IDLE;
  		return -EINVAL;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2145
  	}
14d962602   Dean Anderson   V4L/DVB (8752): s...
2146
2147
2148
  	if (frm->ulState == S2255_READ_IDLE) {
  		frm->ulState = S2255_READ_FRAME;
  		frm->cur_size = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2149
  	}
14d962602   Dean Anderson   V4L/DVB (8752): s...
2150
2151
  	/* skip the marker 512 bytes (and offset if out of sync) */
  	psrc = (u8 *)pipe_info->transfer_buffer + offset;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2152
2153
2154
2155
2156
2157
2158
  	if (frm->lpvbits == NULL) {
  		dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
  			frm, dev, dev->cc, idx);
  		return -ENOMEM;
  	}
  
  	pdest = frm->lpvbits + frm->cur_size;
14d962602   Dean Anderson   V4L/DVB (8752): s...
2159
  	copy_size = (pipe_info->cur_transfer_size - offset);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2160

fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2161
  	size = channel->pkt_size - PREFIX_SIZE;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2162

14d962602   Dean Anderson   V4L/DVB (8752): s...
2163
  	/* sanity check on pdest */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2164
  	if ((copy_size + frm->cur_size) < channel->req_image_size)
14d962602   Dean Anderson   V4L/DVB (8752): s...
2165
  		memcpy(pdest, psrc, copy_size);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2166

38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2167
  	frm->cur_size += copy_size;
14d962602   Dean Anderson   V4L/DVB (8752): s...
2168
2169
2170
2171
  	dprintk(4, "cur_size size %lu size %lu 
  ", frm->cur_size, size);
  
  	if (frm->cur_size >= size) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2172
2173
  		dprintk(2, "****************[%d]Buffer[%d]full*************
  ",
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2174
2175
2176
  			dev->cc, idx);
  		channel->last_frame = channel->cur_frame;
  		channel->cur_frame++;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2177
  		/* end of system frame ring buffer, start at zero */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2178
2179
2180
  		if ((channel->cur_frame == SYS_FRAMES) ||
  		    (channel->cur_frame == channel->buffer.dwFrames))
  			channel->cur_frame = 0;
14d962602   Dean Anderson   V4L/DVB (8752): s...
2181
  		/* frame ready */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2182
2183
2184
  		if (channel->b_acquire)
  			s2255_got_frame(channel, channel->jpg_size);
  		channel->frame_count++;
14d962602   Dean Anderson   V4L/DVB (8752): s...
2185
2186
  		frm->ulState = S2255_READ_IDLE;
  		frm->cur_size = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
  	}
  	/* done successfully */
  	return 0;
  }
  
  static void s2255_read_video_callback(struct s2255_dev *dev,
  				      struct s2255_pipeinfo *pipe_info)
  {
  	int res;
  	dprintk(50, "callback read video 
  ");
  
  	if (dev->cc >= MAX_CHANNELS) {
  		dev->cc = 0;
  		dev_err(&dev->udev->dev, "invalid channel
  ");
  		return;
  	}
  	/* otherwise copy to the system buffers */
  	res = save_frame(dev, pipe_info);
14d962602   Dean Anderson   V4L/DVB (8752): s...
2207
2208
2209
  	if (res != 0)
  		dprintk(4, "s2255: read callback failed
  ");
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
  
  	dprintk(50, "callback read video done
  ");
  	return;
  }
  
  static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
  			     u16 Index, u16 Value, void *TransferBuffer,
  			     s32 TransferBufferLength, int bOut)
  {
  	int r;
  	if (!bOut) {
  		r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
  				    Request,
  				    USB_TYPE_VENDOR | USB_RECIP_DEVICE |
  				    USB_DIR_IN,
  				    Value, Index, TransferBuffer,
  				    TransferBufferLength, HZ * 5);
  	} else {
  		r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
  				    Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  				    Value, Index, TransferBuffer,
  				    TransferBufferLength, HZ * 5);
  	}
  	return r;
  }
  
  /*
   * retrieve FX2 firmware version. future use.
   * @param dev pointer to device extension
   * @return -1 for fail, else returns firmware version as an int(16 bits)
   */
  static int s2255_get_fx2fw(struct s2255_dev *dev)
  {
  	int fw;
  	int ret;
  	unsigned char transBuffer[64];
  	ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
  			       S2255_VR_IN);
  	if (ret < 0)
  		dprintk(2, "get fw error: %x
  ", ret);
  	fw = transBuffer[0] + (transBuffer[1] << 8);
  	dprintk(2, "Get FW %x %x
  ", transBuffer[0], transBuffer[1]);
  	return fw;
  }
  
  /*
   * Create the system ring buffer to copy frames into from the
   * usb read pipe.
   */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2262
  static int s2255_create_sys_buffers(struct s2255_channel *channel)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2263
2264
2265
2266
2267
  {
  	unsigned long i;
  	unsigned long reqsize;
  	dprintk(1, "create sys buffers
  ");
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2268
  	channel->buffer.dwFrames = SYS_FRAMES;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2269
2270
2271
2272
2273
2274
2275
2276
  	/* always allocate maximum size(PAL) for system buffers */
  	reqsize = SYS_FRAMES_MAXSIZE;
  
  	if (reqsize > SYS_FRAMES_MAXSIZE)
  		reqsize = SYS_FRAMES_MAXSIZE;
  
  	for (i = 0; i < SYS_FRAMES; i++) {
  		/* allocate the frames */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2277
2278
2279
2280
2281
2282
2283
  		channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
  		dprintk(1, "valloc %p chan %d, idx %lu, pdata %p
  ",
  			&channel->buffer.frame[i], channel->idx, i,
  			channel->buffer.frame[i].lpvbits);
  		channel->buffer.frame[i].size = reqsize;
  		if (channel->buffer.frame[i].lpvbits == NULL) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2284
2285
  			printk(KERN_INFO "out of memory.  using less frames
  ");
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2286
  			channel->buffer.dwFrames = i;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2287
2288
2289
2290
2291
2292
  			break;
  		}
  	}
  
  	/* make sure internal states are set */
  	for (i = 0; i < SYS_FRAMES; i++) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2293
2294
  		channel->buffer.frame[i].ulState = 0;
  		channel->buffer.frame[i].cur_size = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2295
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2296
2297
  	channel->cur_frame = 0;
  	channel->last_frame = -1;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2298
2299
  	return 0;
  }
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2300
  static int s2255_release_sys_buffers(struct s2255_channel *channel)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2301
2302
2303
2304
2305
  {
  	unsigned long i;
  	dprintk(1, "release sys buffers
  ");
  	for (i = 0; i < SYS_FRAMES; i++) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2306
  		if (channel->buffer.frame[i].lpvbits) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2307
2308
  			dprintk(1, "vfree %p
  ",
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2309
2310
  				channel->buffer.frame[i].lpvbits);
  			vfree(channel->buffer.frame[i].lpvbits);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2311
  		}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2312
  		channel->buffer.frame[i].lpvbits = NULL;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2313
2314
2315
2316
2317
2318
  	}
  	return 0;
  }
  
  static int s2255_board_init(struct s2255_dev *dev)
  {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2319
2320
  	struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
  	int fw_ver;
ab85c6a33   Dean Anderson   V4L/DVB: s2255drv...
2321
2322
  	int j;
  	struct s2255_pipeinfo *pipe = &dev->pipe;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2323
  	dprintk(4, "board init: %p", dev);
ab85c6a33   Dean Anderson   V4L/DVB: s2255drv...
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
  	memset(pipe, 0, sizeof(*pipe));
  	pipe->dev = dev;
  	pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
  	pipe->max_transfer_size = S2255_USB_XFER_SIZE;
  
  	pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
  					GFP_KERNEL);
  	if (pipe->transfer_buffer == NULL) {
  		dprintk(1, "out of memory!
  ");
  		return -ENOMEM;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2335
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2336
2337
  	/* query the firmware */
  	fw_ver = s2255_get_fx2fw(dev);
8a8cc952d   Sensoray Linux Development   [media] s2255drv:...
2338
2339
  	printk(KERN_INFO "s2255: usb firmware version %d.%d
  ",
abce21f40   Dean Anderson   V4L/DVB (11605): ...
2340
2341
2342
2343
  	       (fw_ver >> 8) & 0xff,
  	       fw_ver & 0xff);
  
  	if (fw_ver < S2255_CUR_USB_FWVER)
8a8cc952d   Sensoray Linux Development   [media] s2255drv:...
2344
2345
  		printk(KERN_INFO "s2255: newer USB firmware available
  ");
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2346
2347
  
  	for (j = 0; j < MAX_CHANNELS; j++) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2348
2349
2350
  		struct s2255_channel *channel = &dev->channel[j];
  		channel->b_acquire = 0;
  		channel->mode = mode_def;
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
2351
  		if (dev->pid == 0x2257 && j > 1)
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2352
2353
2354
2355
2356
2357
2358
2359
  			channel->mode.color |= (1 << 16);
  		channel->jc.quality = S2255_DEF_JPEG_QUAL;
  		channel->width = LINE_SZ_4CIFS_NTSC;
  		channel->height = NUM_LINES_4CIFS_NTSC * 2;
  		channel->fmt = &formats[0];
  		channel->mode.restart = 1;
  		channel->req_image_size = get_transfer_size(&mode_def);
  		channel->frame_count = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2360
  		/* create the system buffers */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2361
  		s2255_create_sys_buffers(channel);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2362
2363
2364
  	}
  	/* start read pipe */
  	s2255_start_readpipe(dev);
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
2365
2366
  	dprintk(1, "%s: success
  ", __func__);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2367
2368
2369
2370
2371
2372
  	return 0;
  }
  
  static int s2255_board_shutdown(struct s2255_dev *dev)
  {
  	u32 i;
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
2373
  	dprintk(1, "%s: dev: %p", __func__,  dev);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2374
2375
  
  	for (i = 0; i < MAX_CHANNELS; i++) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2376
2377
  		if (dev->channel[i].b_acquire)
  			s2255_stop_acquire(&dev->channel[i]);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2378
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2379
  	s2255_stop_readpipe(dev);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2380
  	for (i = 0; i < MAX_CHANNELS; i++)
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2381
  		s2255_release_sys_buffers(&dev->channel[i]);
ab85c6a33   Dean Anderson   V4L/DVB: s2255drv...
2382
2383
  	/* release transfer buffer */
  	kfree(dev->pipe.transfer_buffer);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2384
2385
2386
2387
2388
2389
2390
2391
2392
  	return 0;
  }
  
  static void read_pipe_completion(struct urb *purb)
  {
  	struct s2255_pipeinfo *pipe_info;
  	struct s2255_dev *dev;
  	int status;
  	int pipe;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2393
  	pipe_info = purb->context;
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
2394
2395
  	dprintk(100, "%s: urb:%p, status %d
  ", __func__, purb,
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2396
2397
  		purb->status);
  	if (pipe_info == NULL) {
be9ed5117   Mauro Carvalho Chehab   V4L/DVB (10298): ...
2398
2399
  		dev_err(&purb->dev->dev, "no context!
  ");
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2400
2401
2402
2403
2404
  		return;
  	}
  
  	dev = pipe_info->dev;
  	if (dev == NULL) {
be9ed5117   Mauro Carvalho Chehab   V4L/DVB (10298): ...
2405
2406
  		dev_err(&purb->dev->dev, "no context!
  ");
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2407
2408
2409
  		return;
  	}
  	status = purb->status;
b02064cae   Dean Anderson   V4L/DVB (11738): ...
2410
2411
  	/* if shutting down, do not resubmit, exit immediately */
  	if (status == -ESHUTDOWN) {
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
2412
2413
  		dprintk(2, "%s: err shutdown
  ", __func__);
b02064cae   Dean Anderson   V4L/DVB (11738): ...
2414
  		pipe_info->err_count++;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2415
2416
2417
2418
  		return;
  	}
  
  	if (pipe_info->state == 0) {
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
2419
  		dprintk(2, "%s: exiting USB pipe", __func__);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2420
2421
  		return;
  	}
b02064cae   Dean Anderson   V4L/DVB (11738): ...
2422
2423
2424
2425
  	if (status == 0)
  		s2255_read_video_callback(dev, pipe_info);
  	else {
  		pipe_info->err_count++;
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
2426
2427
  		dprintk(1, "%s: failed URB %d
  ", __func__, status);
b02064cae   Dean Anderson   V4L/DVB (11738): ...
2428
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2429

38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2430
2431
2432
2433
2434
2435
2436
2437
2438
  	pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
  	/* reuse urb */
  	usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
  			  pipe,
  			  pipe_info->transfer_buffer,
  			  pipe_info->cur_transfer_size,
  			  read_pipe_completion, pipe_info);
  
  	if (pipe_info->state != 0) {
a1b4c86b2   Pete Eberlein   [media] s2255drv:...
2439
  		if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2440
2441
  			dev_err(&dev->udev->dev, "error submitting urb
  ");
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2442
2443
  		}
  	} else {
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
2444
2445
  		dprintk(2, "%s :complete state 0
  ", __func__);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2446
2447
2448
2449
2450
2451
2452
2453
  	}
  	return;
  }
  
  static int s2255_start_readpipe(struct s2255_dev *dev)
  {
  	int pipe;
  	int retval;
ab85c6a33   Dean Anderson   V4L/DVB: s2255drv...
2454
  	struct s2255_pipeinfo *pipe_info = &dev->pipe;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2455
  	pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
2456
2457
  	dprintk(2, "%s: IN %d
  ", __func__, dev->read_endpoint);
ab85c6a33   Dean Anderson   V4L/DVB: s2255drv...
2458
2459
2460
2461
2462
2463
2464
2465
  	pipe_info->state = 1;
  	pipe_info->err_count = 0;
  	pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
  	if (!pipe_info->stream_urb) {
  		dev_err(&dev->udev->dev,
  			"ReadStream: Unable to alloc URB
  ");
  		return -ENOMEM;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2466
  	}
ab85c6a33   Dean Anderson   V4L/DVB: s2255drv...
2467
2468
2469
2470
2471
2472
  	/* transfer buffer allocated in board_init */
  	usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
  			  pipe,
  			  pipe_info->transfer_buffer,
  			  pipe_info->cur_transfer_size,
  			  read_pipe_completion, pipe_info);
ab85c6a33   Dean Anderson   V4L/DVB: s2255drv...
2473
2474
2475
2476
2477
2478
  	retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
  	if (retval) {
  		printk(KERN_ERR "s2255: start read pipe failed
  ");
  		return retval;
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2479
2480
2481
2482
  	return 0;
  }
  
  /* starts acquisition process */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2483
  static int s2255_start_acquire(struct s2255_channel *channel)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2484
2485
2486
2487
2488
  {
  	unsigned char *buffer;
  	int res;
  	unsigned long chn_rev;
  	int j;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2489
2490
  	struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
  	chn_rev = G_chnmap[channel->idx];
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2491
2492
2493
2494
2495
2496
  	buffer = kzalloc(512, GFP_KERNEL);
  	if (buffer == NULL) {
  		dev_err(&dev->udev->dev, "out of mem
  ");
  		return -ENOMEM;
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2497
2498
2499
  	channel->last_frame = -1;
  	channel->bad_payload = 0;
  	channel->cur_frame = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2500
  	for (j = 0; j < SYS_FRAMES; j++) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2501
2502
  		channel->buffer.frame[j].ulState = 0;
  		channel->buffer.frame[j].cur_size = 0;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2503
2504
2505
  	}
  
  	/* send the start command */
3fa006052   Dean Anderson   V4L/DVB: s2255drv...
2506
2507
2508
  	*(__le32 *) buffer = IN_DATA_TOKEN;
  	*((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
  	*((__le32 *) buffer + 2) = CMD_START;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2509
2510
2511
2512
  	res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
  	if (res != 0)
  		dev_err(&dev->udev->dev, "CMD_START error
  ");
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2513
2514
  	dprintk(2, "start acquire exit[%d] %d 
  ", channel->idx, res);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2515
2516
2517
  	kfree(buffer);
  	return 0;
  }
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2518
  static int s2255_stop_acquire(struct s2255_channel *channel)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2519
2520
2521
2522
  {
  	unsigned char *buffer;
  	int res;
  	unsigned long chn_rev;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2523
2524
  	struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
  	chn_rev = G_chnmap[channel->idx];
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2525
2526
2527
2528
2529
2530
  	buffer = kzalloc(512, GFP_KERNEL);
  	if (buffer == NULL) {
  		dev_err(&dev->udev->dev, "out of mem
  ");
  		return -ENOMEM;
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2531
  	/* send the stop command */
3fa006052   Dean Anderson   V4L/DVB: s2255drv...
2532
2533
2534
  	*(__le32 *) buffer = IN_DATA_TOKEN;
  	*((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
  	*((__le32 *) buffer + 2) = CMD_STOP;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2535
  	res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2536
2537
2538
  	if (res != 0)
  		dev_err(&dev->udev->dev, "CMD_STOP error
  ");
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2539
  	kfree(buffer);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2540
2541
2542
  	channel->b_acquire = 0;
  	dprintk(4, "%s: chn %d, res %d
  ", __func__, channel->idx, res);
14d962602   Dean Anderson   V4L/DVB (8752): s...
2543
  	return res;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2544
2545
2546
2547
  }
  
  static void s2255_stop_readpipe(struct s2255_dev *dev)
  {
ab85c6a33   Dean Anderson   V4L/DVB: s2255drv...
2548
  	struct s2255_pipeinfo *pipe = &dev->pipe;
8b661b508   Dan Carpenter   V4L/DVB: s2255drv...
2549

ab85c6a33   Dean Anderson   V4L/DVB: s2255drv...
2550
2551
2552
2553
2554
2555
  	pipe->state = 0;
  	if (pipe->stream_urb) {
  		/* cancel urb */
  		usb_kill_urb(pipe->stream_urb);
  		usb_free_urb(pipe->stream_urb);
  		pipe->stream_urb = NULL;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2556
  	}
ab85c6a33   Dean Anderson   V4L/DVB: s2255drv...
2557
  	dprintk(4, "%s", __func__);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2558
2559
  	return;
  }
14d962602   Dean Anderson   V4L/DVB (8752): s...
2560
  static void s2255_fwload_start(struct s2255_dev *dev, int reset)
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2561
  {
14d962602   Dean Anderson   V4L/DVB (8752): s...
2562
2563
  	if (reset)
  		s2255_reset_dsppower(dev);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
  	dev->fw_data->fw_size = dev->fw_data->fw->size;
  	atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
  	memcpy(dev->fw_data->pfw_data,
  	       dev->fw_data->fw->data, CHUNK_SIZE);
  	dev->fw_data->fw_loaded = CHUNK_SIZE;
  	usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
  			  usb_sndbulkpipe(dev->udev, 2),
  			  dev->fw_data->pfw_data,
  			  CHUNK_SIZE, s2255_fwchunk_complete,
  			  dev->fw_data);
  	mod_timer(&dev->timer, jiffies + HZ);
  }
  
  /* standard usb probe function */
  static int s2255_probe(struct usb_interface *interface,
  		       const struct usb_device_id *id)
  {
  	struct s2255_dev *dev = NULL;
  	struct usb_host_interface *iface_desc;
  	struct usb_endpoint_descriptor *endpoint;
  	int i;
  	int retval = -ENOMEM;
14d962602   Dean Anderson   V4L/DVB (8752): s...
2586
2587
  	__le32 *pdata;
  	int fw_size;
85b85482c   Dean Anderson   V4L/DVB: s2255drv...
2588
2589
  	dprintk(2, "%s
  ", __func__);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2590
2591
2592
  	/* allocate memory for our device state and initialize it to zero */
  	dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
  	if (dev == NULL) {
be9ed5117   Mauro Carvalho Chehab   V4L/DVB (10298): ...
2593
2594
  		s2255_dev_err(&interface->dev, "out of memory
  ");
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2595
  		return -ENOMEM;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2596
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2597
  	atomic_set(&dev->num_channels, 0);
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
2598
  	dev->pid = id->idProduct;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2599
2600
  	dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
  	if (!dev->fw_data)
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2601
  		goto errorFWDATA1;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2602
2603
  	mutex_init(&dev->lock);
  	mutex_init(&dev->open_lock);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2604
2605
2606
2607
2608
2609
  	/* grab usb_device and save it */
  	dev->udev = usb_get_dev(interface_to_usbdev(interface));
  	if (dev->udev == NULL) {
  		dev_err(&interface->dev, "null usb device
  ");
  		retval = -ENODEV;
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2610
  		goto errorUDEV;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2611
  	}
d62e85a09   Dean Anderson   V4L/DVB: s2255drv...
2612
2613
  	dprintk(1, "dev: %p, udev %p interface %p
  ", dev,
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
  		dev->udev, interface);
  	dev->interface = interface;
  	/* set up the endpoint information  */
  	iface_desc = interface->cur_altsetting;
  	dprintk(1, "num endpoints %d
  ", iface_desc->desc.bNumEndpoints);
  	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
  		endpoint = &iface_desc->endpoint[i].desc;
  		if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
  			/* we found the bulk in endpoint */
  			dev->read_endpoint = endpoint->bEndpointAddress;
  		}
  	}
  
  	if (!dev->read_endpoint) {
be9ed5117   Mauro Carvalho Chehab   V4L/DVB (10298): ...
2629
2630
  		dev_err(&interface->dev, "Could not find bulk-in endpoint
  ");
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2631
  		goto errorEP;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2632
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2633
2634
2635
  	init_timer(&dev->timer);
  	dev->timer.function = s2255_timer;
  	dev->timer.data = (unsigned long)dev->fw_data;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2636
  	init_waitqueue_head(&dev->fw_data->wait_fw);
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
2637
  	for (i = 0; i < MAX_CHANNELS; i++) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2638
2639
2640
2641
  		struct s2255_channel *channel = &dev->channel[i];
  		dev->channel[i].idx = i;
  		init_waitqueue_head(&channel->wait_setmode);
  		init_waitqueue_head(&channel->wait_vidstatus);
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
2642
  	}
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2643
2644
  
  	dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2645
2646
2647
  	if (!dev->fw_data->fw_urb) {
  		dev_err(&interface->dev, "out of memory!
  ");
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2648
  		goto errorFWURB;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2649
  	}
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2650

38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2651
2652
2653
2654
  	dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
  	if (!dev->fw_data->pfw_data) {
  		dev_err(&interface->dev, "out of memory!
  ");
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2655
  		goto errorFWDATA2;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2656
2657
2658
2659
2660
2661
  	}
  	/* load the first chunk */
  	if (request_firmware(&dev->fw_data->fw,
  			     FIRMWARE_FILE_NAME, &dev->udev->dev)) {
  		printk(KERN_ERR "sensoray 2255 failed to get firmware
  ");
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2662
  		goto errorREQFW;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2663
  	}
14d962602   Dean Anderson   V4L/DVB (8752): s...
2664
2665
2666
  	/* check the firmware is valid */
  	fw_size = dev->fw_data->fw->size;
  	pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2667

14d962602   Dean Anderson   V4L/DVB (8752): s...
2668
2669
2670
2671
  	if (*pdata != S2255_FW_MARKER) {
  		printk(KERN_INFO "Firmware invalid.
  ");
  		retval = -ENODEV;
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2672
  		goto errorFWMARKER;
14d962602   Dean Anderson   V4L/DVB (8752): s...
2673
2674
2675
2676
2677
2678
  	} else {
  		/* make sure firmware is the latest */
  		__le32 *pRel;
  		pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
  		printk(KERN_INFO "s2255 dsp fw version %x
  ", *pRel);
4de39f5d6   Dean Anderson   V4L/DVB: s2255drv...
2679
2680
2681
2682
  		dev->dsp_fw_ver = *pRel;
  		if (*pRel < S2255_CUR_DSP_FWVER)
  			printk(KERN_INFO "s2255: f2255usb.bin out of date.
  ");
5a34d9dfa   Dean Anderson   V4L/DVB: s2255drv...
2683
  		if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2684
  			printk(KERN_WARNING "s2255: 2257 requires firmware %d"
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2685
2686
  			       " or above.
  ", S2255_MIN_DSP_COLORFILTER);
14d962602   Dean Anderson   V4L/DVB (8752): s...
2687
  	}
14d962602   Dean Anderson   V4L/DVB (8752): s...
2688
  	usb_reset_device(dev->udev);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2689
  	/* load 2255 board specific */
abce21f40   Dean Anderson   V4L/DVB (11605): ...
2690
2691
  	retval = s2255_board_init(dev);
  	if (retval)
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2692
  		goto errorBOARDINIT;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2693
  	spin_lock_init(&dev->slock);
14d962602   Dean Anderson   V4L/DVB (8752): s...
2694
  	s2255_fwload_start(dev, 0);
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2695
2696
2697
  	/* loads v4l specific */
  	retval = s2255_probe_v4l(dev);
  	if (retval)
3a67b5cc6   Dean Anderson   V4L/DVB: s2255drv...
2698
  		goto errorBOARDINIT;
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2699
2700
2701
  	dev_info(&interface->dev, "Sensoray 2255 detected
  ");
  	return 0;
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
  errorBOARDINIT:
  	s2255_board_shutdown(dev);
  errorFWMARKER:
  	release_firmware(dev->fw_data->fw);
  errorREQFW:
  	kfree(dev->fw_data->pfw_data);
  errorFWDATA2:
  	usb_free_urb(dev->fw_data->fw_urb);
  errorFWURB:
  	del_timer(&dev->timer);
  errorEP:
  	usb_put_dev(dev->udev);
  errorUDEV:
  	kfree(dev->fw_data);
  	mutex_destroy(&dev->open_lock);
  	mutex_destroy(&dev->lock);
  errorFWDATA1:
  	kfree(dev);
  	printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x
  ", retval);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2722
2723
2724
2725
2726
2727
  	return retval;
  }
  
  /* disconnect routine. when board is removed physically or with rmmod */
  static void s2255_disconnect(struct usb_interface *interface)
  {
65c6edb30   Dean Anderson   V4L/DVB: s2255drv...
2728
  	struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
14d962602   Dean Anderson   V4L/DVB (8752): s...
2729
  	int i;
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2730
  	int channels = atomic_read(&dev->num_channels);
a19a5cd7b   Pete Eberlein   [media] s2255drv:...
2731
  	mutex_lock(&dev->lock);
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2732
  	v4l2_device_disconnect(&dev->v4l2_dev);
a19a5cd7b   Pete Eberlein   [media] s2255drv:...
2733
  	mutex_unlock(&dev->lock);
d62e85a09   Dean Anderson   V4L/DVB: s2255drv...
2734
  	/*see comments in the uvc_driver.c usb disconnect function */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2735
  	atomic_inc(&dev->num_channels);
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2736
  	/* unregister each video device. */
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2737
2738
  	for (i = 0; i < channels; i++)
  		video_unregister_device(&dev->channel[i].vdev);
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2739
  	/* wake up any of our timers */
14d962602   Dean Anderson   V4L/DVB (8752): s...
2740
2741
2742
  	atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
  	wake_up(&dev->fw_data->wait_fw);
  	for (i = 0; i < MAX_CHANNELS; i++) {
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2743
2744
2745
2746
  		dev->channel[i].setmode_ready = 1;
  		wake_up(&dev->channel[i].wait_setmode);
  		dev->channel[i].vidstatus_ready = 1;
  		wake_up(&dev->channel[i].wait_vidstatus);
14d962602   Dean Anderson   V4L/DVB (8752): s...
2747
  	}
fe85ce90a   Dean Anderson   V4L/DVB: s2255drv...
2748
  	if (atomic_dec_and_test(&dev->num_channels))
d62e85a09   Dean Anderson   V4L/DVB: s2255drv...
2749
  		s2255_destroy(dev);
ff7e22dfa   Dean Anderson   V4L/DVB: s2255drv...
2750
2751
  	dev_info(&interface->dev, "%s
  ", __func__);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2752
2753
2754
  }
  
  static struct usb_driver s2255_driver = {
be9ed5117   Mauro Carvalho Chehab   V4L/DVB (10298): ...
2755
  	.name = S2255_DRIVER_NAME,
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2756
2757
2758
2759
  	.probe = s2255_probe,
  	.disconnect = s2255_disconnect,
  	.id_table = s2255_table,
  };
ecb3b2b35   Greg Kroah-Hartman   USB: convert driv...
2760
  module_usb_driver(s2255_driver);
38f993ad8   Dean Anderson   V4L/DVB (8125): T...
2761
2762
2763
2764
  
  MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
  MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
  MODULE_LICENSE("GPL");
64dc3c1a9   Mauro Carvalho Chehab   [media] Stop usin...
2765
  MODULE_VERSION(S2255_VERSION);