Blame view
drivers/media/video/s2255drv.c
75.5 KB
38f993ad8 V4L/DVB (8125): T... |
1 2 3 |
/* * s2255drv.c - a driver for the Sensoray 2255 USB video capture device * |
4de39f5d6 V4L/DVB: s2255drv... |
4 |
* Copyright (C) 2007-2010 by Sensoray Company Inc. |
38f993ad8 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 V4L/DVB (8125): T... |
19 |
* -full or half size Grey scale: all 4 channels at once |
38f993ad8 V4L/DVB (8125): T... |
20 |
* -half size, color mode YUYV or YUV422P: all 4 channels at once |
38f993ad8 V4L/DVB (8125): T... |
21 22 |
* -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels * at once. |
38f993ad8 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 include cleanup: ... |
43 |
#include <linux/slab.h> |
38f993ad8 V4L/DVB (8125): T... |
44 |
#include <linux/videodev2.h> |
feb75f071 V4L/DVB (8504): s... |
45 |
#include <linux/mm.h> |
38f993ad8 V4L/DVB (8125): T... |
46 47 |
#include <media/videobuf-vmalloc.h> #include <media/v4l2-common.h> |
3a67b5cc6 V4L/DVB: s2255drv... |
48 |
#include <media/v4l2-device.h> |
35ea11ff8 V4L/DVB (8430): v... |
49 |
#include <media/v4l2-ioctl.h> |
38f993ad8 V4L/DVB (8125): T... |
50 51 |
#include <linux/vmalloc.h> #include <linux/usb.h> |
64dc3c1a9 [media] Stop usin... |
52 |
#define S2255_VERSION "1.22.1" |
38f993ad8 V4L/DVB (8125): T... |
53 |
#define FIRMWARE_FILE_NAME "f2255usb.bin" |
22b88d48a V4L/DVB (8845): s... |
54 55 |
/* default JPEG quality */ #define S2255_DEF_JPEG_QUAL 50 |
38f993ad8 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 V4L/DVB (8752): s... |
65 |
#define S2255_DSP_BOOTTIME 800 |
38f993ad8 V4L/DVB (8125): T... |
66 |
/* maximum time to wait for firmware to load (ms) */ |
3f8d6f73d V4L/DVB (8317): S... |
67 |
#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME) |
38f993ad8 V4L/DVB (8125): T... |
68 |
#define S2255_DEF_BUFS 16 |
14d962602 V4L/DVB (8752): s... |
69 |
#define S2255_SETMODE_TIMEOUT 500 |
4de39f5d6 V4L/DVB: s2255drv... |
70 |
#define S2255_VIDSTATUS_TIMEOUT 350 |
3fa006052 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 V4L/DVB (8752): s... |
76 |
#define S2255_USB_XFER_SIZE (16 * 1024) |
38f993ad8 V4L/DVB (8125): T... |
77 |
#define MAX_CHANNELS 4 |
38f993ad8 V4L/DVB (8125): T... |
78 79 |
#define SYS_FRAMES 4 /* maximum size is PAL full size plus room for the marker header(s) */ |
14d962602 V4L/DVB (8752): s... |
80 81 |
#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096) #define DEF_USB_BLOCK S2255_USB_XFER_SIZE |
38f993ad8 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 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 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 V4L/DVB (8752): s... |
111 |
#define COLOR_JPG 5 /* JPEG */ |
38f993ad8 V4L/DVB (8125): T... |
112 |
|
5a34d9dfa V4L/DVB: s2255drv... |
113 114 115 |
#define MASK_COLOR 0x000000ff #define MASK_JPG_QUALITY 0x0000ff00 #define MASK_INPUT_TYPE 0x000f0000 |
8a8cc952d [media] s2255drv:... |
116 |
/* frame decimation. */ |
38f993ad8 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 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 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 V4L/DVB (8125): T... |
154 |
|
14d962602 V4L/DVB (8752): s... |
155 156 |
#define S2255_READ_IDLE 0 #define S2255_READ_FRAME 1 |
38f993ad8 V4L/DVB (8125): T... |
157 |
|
14d962602 V4L/DVB (8752): s... |
158 |
/* frame structure */ |
38f993ad8 V4L/DVB (8125): T... |
159 160 |
struct s2255_framei { unsigned long size; |
14d962602 V4L/DVB (8752): s... |
161 |
unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/ |
38f993ad8 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 V4L/DVB (8317): S... |
174 |
DEF_HUE, 0, DEF_USB_BLOCK, 0} |
38f993ad8 V4L/DVB (8125): T... |
175 176 177 |
struct s2255_dmaqueue { struct list_head active; |
38f993ad8 V4L/DVB (8125): T... |
178 |
struct s2255_dev *dev; |
38f993ad8 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 V4L/DVB (8490): s... |
186 |
#define S2255_FW_DISCONNECTING 4 |
deaf53e3c V4L/DVB (9635): v... |
187 |
#define S2255_FW_MARKER cpu_to_le32(0x22552f2f) |
14d962602 V4L/DVB (8752): s... |
188 189 190 |
/* 2255 read states */ #define S2255_READ_IDLE 0 #define S2255_READ_FRAME 1 |
38f993ad8 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 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 V4L/DVB (8125): T... |
205 |
u32 state; |
38f993ad8 V4L/DVB (8125): T... |
206 207 208 |
void *stream_urb; void *dev; /* back pointer to s2255_dev struct*/ u32 err_count; |
38f993ad8 V4L/DVB (8125): T... |
209 |
u32 idx; |
38f993ad8 V4L/DVB (8125): T... |
210 211 212 |
}; struct s2255_fmt; /*forward declaration */ |
fe85ce90a 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 V4L/DVB (8125): T... |
250 251 |
struct s2255_dev { |
fe85ce90a V4L/DVB: s2255drv... |
252 |
struct s2255_channel channel[MAX_CHANNELS]; |
65c6edb30 V4L/DVB: s2255drv... |
253 |
struct v4l2_device v4l2_dev; |
fe85ce90a V4L/DVB: s2255drv... |
254 |
atomic_t num_channels; |
38f993ad8 V4L/DVB (8125): T... |
255 |
int frames; |
a19a5cd7b [media] s2255drv:... |
256 |
struct mutex lock; /* channels[].vdev.lock */ |
38f993ad8 V4L/DVB (8125): T... |
257 |
struct mutex open_lock; |
38f993ad8 V4L/DVB (8125): T... |
258 259 260 |
struct usb_device *udev; struct usb_interface *interface; u8 read_endpoint; |
38f993ad8 V4L/DVB (8125): T... |
261 262 |
struct timer_list timer; struct s2255_fw *fw_data; |
ab85c6a33 V4L/DVB: s2255drv... |
263 |
struct s2255_pipeinfo pipe; |
38f993ad8 V4L/DVB (8125): T... |
264 |
u32 cc; /* current channel */ |
38f993ad8 V4L/DVB (8125): T... |
265 |
int frame_ready; |
14d962602 V4L/DVB (8752): s... |
266 |
int chn_ready; |
38f993ad8 V4L/DVB (8125): T... |
267 |
spinlock_t slock; |
4de39f5d6 V4L/DVB: s2255drv... |
268 269 |
/* dsp firmware version (f2255usb.bin) */ int dsp_fw_ver; |
5a34d9dfa V4L/DVB: s2255drv... |
270 |
u16 pid; /* product id */ |
38f993ad8 V4L/DVB (8125): T... |
271 |
}; |
65c6edb30 V4L/DVB: s2255drv... |
272 |
|
65c6edb30 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 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 V4L/DVB (8125): T... |
293 294 |
struct videobuf_queue vb_vidq; enum v4l2_buf_type type; |
fe85ce90a V4L/DVB: s2255drv... |
295 296 |
struct s2255_channel *channel; int resources; |
38f993ad8 V4L/DVB (8125): T... |
297 |
}; |
abce21f40 V4L/DVB (11605): ... |
298 |
/* current cypress EEPROM firmware version */ |
8a8cc952d [media] s2255drv:... |
299 |
#define S2255_CUR_USB_FWVER ((3 << 8) | 12) |
4de39f5d6 V4L/DVB: s2255drv... |
300 |
/* current DSP FW version */ |
8a8cc952d [media] s2255drv:... |
301 |
#define S2255_CUR_DSP_FWVER 10104 |
4de39f5d6 V4L/DVB: s2255drv... |
302 |
/* Need DSP version 5+ for video status feature */ |
5a34d9dfa V4L/DVB: s2255drv... |
303 304 |
#define S2255_MIN_DSP_STATUS 5 #define S2255_MIN_DSP_COLORFILTER 8 |
38f993ad8 V4L/DVB (8125): T... |
305 |
#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC) |
5a34d9dfa 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 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 V4L/DVB (8317): S... |
340 |
static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0}; |
38f993ad8 V4L/DVB (8125): T... |
341 |
|
38f993ad8 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 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 V4L/DVB (8125): T... |
352 |
static int s2255_board_shutdown(struct s2255_dev *dev); |
14d962602 V4L/DVB (8752): s... |
353 |
static void s2255_fwload_start(struct s2255_dev *dev, int reset); |
d62e85a09 V4L/DVB: s2255drv... |
354 |
static void s2255_destroy(struct s2255_dev *dev); |
14d962602 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 V4L/DVB (8125): T... |
358 |
|
be9ed5117 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 V4L/DVB (8125): T... |
363 364 365 |
#define dprintk(level, fmt, arg...) \ do { \ if (*s2255_debug >= (level)) { \ |
be9ed5117 V4L/DVB (10298): ... |
366 367 |
printk(KERN_DEBUG S2255_DRIVER_NAME \ ": " fmt, ##arg); \ |
38f993ad8 V4L/DVB (8125): T... |
368 369 |
} \ } while (0) |
38f993ad8 V4L/DVB (8125): T... |
370 |
static struct usb_driver s2255_driver; |
38f993ad8 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 [media] s2255drv:... |
376 377 |
/* Enable jpeg capture. */ static int jpeg_enable = 1; |
3f8d6f73d V4L/DVB (8317): S... |
378 |
module_param(debug, int, 0644); |
38f993ad8 V4L/DVB (8125): T... |
379 |
MODULE_PARM_DESC(debug, "Debug level(0-100) default 0"); |
3f8d6f73d V4L/DVB (8317): S... |
380 |
module_param(vid_limit, int, 0644); |
38f993ad8 V4L/DVB (8125): T... |
381 |
MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)"); |
3f8d6f73d V4L/DVB (8317): S... |
382 |
module_param(video_nr, int, 0644); |
38f993ad8 V4L/DVB (8125): T... |
383 |
MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)"); |
e42e28f9d [media] s2255drv:... |
384 385 |
module_param(jpeg_enable, int, 0644); MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1"); |
38f993ad8 V4L/DVB (8125): T... |
386 387 |
/* USB device table */ |
5a34d9dfa V4L/DVB: s2255drv... |
388 |
#define USB_SENSORAY_VID 0x1943 |
38f993ad8 V4L/DVB (8125): T... |
389 |
static struct usb_device_id s2255_table[] = { |
5a34d9dfa V4L/DVB: s2255drv... |
390 391 |
{USB_DEVICE(USB_SENSORAY_VID, 0x2255)}, {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/ |
38f993ad8 V4L/DVB (8125): T... |
392 393 394 |
{ } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, s2255_table); |
38f993ad8 V4L/DVB (8125): T... |
395 |
#define BUFFER_TIMEOUT msecs_to_jiffies(400) |
38f993ad8 V4L/DVB (8125): T... |
396 |
/* image formats. */ |
e42e28f9d [media] s2255drv:... |
397 |
/* JPEG formats must be defined last to support jpeg_enable parameter */ |
38f993ad8 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 [media] s2255drv:... |
414 415 416 417 |
.name = "8bpp GREY", .fourcc = V4L2_PIX_FMT_GREY, .depth = 8 }, { |
14d962602 V4L/DVB (8752): s... |
418 419 420 421 |
.name = "JPG", .fourcc = V4L2_PIX_FMT_JPEG, .depth = 24 }, { |
d0ef8540f [media] s2255drv:... |
422 423 424 |
.name = "MJPG", .fourcc = V4L2_PIX_FMT_MJPEG, .depth = 24 |
38f993ad8 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 V4L/DVB (8317): S... |
451 452 453 454 |
/* * TODO: fixme: move YUV reordering to hardware * converts 2255 planar format to yuyv or uyvy */ |
38f993ad8 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 V4L/DVB (8906): v... |
476 |
static void s2255_reset_dsppower(struct s2255_dev *dev) |
14d962602 V4L/DVB (8752): s... |
477 |
{ |
8a8cc952d [media] s2255drv:... |
478 |
s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1); |
14d962602 V4L/DVB (8752): s... |
479 480 |
msleep(10); s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1); |
752eb7ae5 [media] s2255drv:... |
481 482 |
msleep(600); s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1); |
14d962602 V4L/DVB (8752): s... |
483 484 |
return; } |
38f993ad8 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 V4L/DVB: s2255drv... |
491 492 |
dprintk(100, "%s ", __func__); |
38f993ad8 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 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 V4L/DVB (8125): T... |
499 500 501 |
return; } } |
38f993ad8 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 V4L/DVB: s2255drv... |
514 |
dprintk(100, "%s: udev %p urb %p", __func__, udev, urb); |
38f993ad8 V4L/DVB (8125): T... |
515 |
if (urb->status) { |
be9ed5117 V4L/DVB (10298): ... |
516 517 |
dev_err(&udev->dev, "URB failed with status %d ", urb->status); |
f78d92c9f 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 V4L/DVB (8125): T... |
521 522 523 |
return; } if (data->fw_urb == NULL) { |
be9ed5117 V4L/DVB (10298): ... |
524 525 |
s2255_dev_err(&udev->dev, "disconnected "); |
f78d92c9f 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 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 V4L/DVB (8125): T... |
563 |
atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT); |
85b85482c V4L/DVB: s2255drv... |
564 565 |
dprintk(100, "%s: firmware upload complete ", __func__); |
38f993ad8 V4L/DVB (8125): T... |
566 |
} |
38f993ad8 V4L/DVB (8125): T... |
567 568 569 |
return; } |
fe85ce90a V4L/DVB: s2255drv... |
570 |
static int s2255_got_frame(struct s2255_channel *channel, int jpgsize) |
38f993ad8 V4L/DVB (8125): T... |
571 |
{ |
fe85ce90a V4L/DVB: s2255drv... |
572 |
struct s2255_dmaqueue *dma_q = &channel->vidq; |
38f993ad8 V4L/DVB (8125): T... |
573 |
struct s2255_buffer *buf; |
fe85ce90a V4L/DVB: s2255drv... |
574 |
struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); |
38f993ad8 V4L/DVB (8125): T... |
575 576 |
unsigned long flags = 0; int rc = 0; |
38f993ad8 V4L/DVB (8125): T... |
577 |
spin_lock_irqsave(&dev->slock, flags); |
38f993ad8 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 V4L/DVB (8125): T... |
586 587 |
list_del(&buf->vb.queue); do_gettimeofday(&buf->vb.ts); |
fe85ce90a V4L/DVB: s2255drv... |
588 |
s2255_fillbuff(channel, buf, jpgsize); |
38f993ad8 V4L/DVB (8125): T... |
589 |
wake_up(&buf->vb.done); |
85b85482c V4L/DVB: s2255drv... |
590 591 |
dprintk(2, "%s: [buf/i] [%p/%d] ", __func__, buf, buf->vb.i); |
38f993ad8 V4L/DVB (8125): T... |
592 593 |
unlock: spin_unlock_irqrestore(&dev->slock, flags); |
f27709792 V4L/DVB: drivers/... |
594 |
return rc; |
38f993ad8 V4L/DVB (8125): T... |
595 |
} |
38f993ad8 V4L/DVB (8125): T... |
596 597 598 |
static const struct s2255_fmt *format_by_fourcc(int fourcc) { unsigned int i; |
38f993ad8 V4L/DVB (8125): T... |
599 600 601 |
for (i = 0; i < ARRAY_SIZE(formats); i++) { if (-1 == formats[i].fourcc) continue; |
e42e28f9d [media] s2255drv:... |
602 603 604 |
if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) || (formats[i].fourcc == V4L2_PIX_FMT_MJPEG))) continue; |
38f993ad8 V4L/DVB (8125): T... |
605 606 607 608 609 |
if (formats[i].fourcc == fourcc) return formats + i; } return NULL; } |
38f993ad8 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 V4L/DVB: s2255drv... |
618 619 |
static void s2255_fillbuff(struct s2255_channel *channel, struct s2255_buffer *buf, int jpgsize) |
38f993ad8 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 V4L/DVB: s2255drv... |
630 |
last_frame = channel->last_frame; |
38f993ad8 V4L/DVB (8125): T... |
631 |
if (last_frame != -1) { |
fe85ce90a V4L/DVB: s2255drv... |
632 |
frm = &channel->buffer.frame[last_frame]; |
38f993ad8 V4L/DVB (8125): T... |
633 |
tmpbuf = |
fe85ce90a V4L/DVB: s2255drv... |
634 |
(const char *)channel->buffer.frame[last_frame].lpvbits; |
38f993ad8 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 V4L/DVB (8752): s... |
646 |
case V4L2_PIX_FMT_JPEG: |
d0ef8540f [media] s2255drv:... |
647 |
case V4L2_PIX_FMT_MJPEG: |
14d962602 V4L/DVB (8752): s... |
648 649 650 |
buf->vb.size = jpgsize; memcpy(vbuf, tmpbuf, buf->vb.size); break; |
38f993ad8 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 V4L/DVB: s2255drv... |
659 |
channel->last_frame = -1; |
38f993ad8 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 V4L/DVB: s2255drv... |
670 |
buf->vb.field_count = channel->frame_count * 2; |
38f993ad8 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 V4L/DVB: s2255drv... |
685 686 |
struct s2255_channel *channel = fh->channel; *size = channel->width * channel->height * (channel->fmt->depth >> 3); |
38f993ad8 V4L/DVB (8125): T... |
687 688 689 |
if (0 == *count) *count = S2255_DEF_BUFS; |
dab7e3106 V4L/DVB: V4L2: Re... |
690 691 |
if (*size * *count > vid_limit * 1024 * 1024) *count = (vid_limit * 1024 * 1024) / *size; |
38f993ad8 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 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 V4L/DVB: s2255drv... |
708 |
struct s2255_channel *channel = fh->channel; |
38f993ad8 V4L/DVB (8125): T... |
709 710 |
struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb); int rc; |
fe85ce90a V4L/DVB: s2255drv... |
711 712 |
int w = channel->width; int h = channel->height; |
38f993ad8 V4L/DVB (8125): T... |
713 714 |
dprintk(4, "%s, field=%d ", __func__, field); |
fe85ce90a V4L/DVB: s2255drv... |
715 |
if (channel->fmt == NULL) |
38f993ad8 V4L/DVB (8125): T... |
716 |
return -EINVAL; |
fe85ce90a 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 V4L/DVB (8125): T... |
721 722 723 724 |
dprintk(4, "invalid buffer prepare "); return -EINVAL; } |
fe85ce90a V4L/DVB: s2255drv... |
725 |
buf->vb.size = w * h * (channel->fmt->depth >> 3); |
38f993ad8 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 V4L/DVB: s2255drv... |
731 732 733 |
buf->fmt = channel->fmt; buf->vb.width = w; buf->vb.height = h; |
38f993ad8 V4L/DVB (8125): T... |
734 |
buf->vb.field = field; |
38f993ad8 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 V4L/DVB: s2255drv... |
752 753 |
struct s2255_channel *channel = fh->channel; struct s2255_dmaqueue *vidq = &channel->vidq; |
38f993ad8 V4L/DVB (8125): T... |
754 755 |
dprintk(1, "%s ", __func__); |
38f993ad8 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 V4L/DVB: s2255drv... |
765 766 |
dprintk(4, "%s %d ", __func__, fh->channel->idx); |
38f993ad8 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 V4L/DVB: s2255drv... |
776 |
static int res_get(struct s2255_fh *fh) |
38f993ad8 V4L/DVB (8125): T... |
777 |
{ |
fe85ce90a V4L/DVB: s2255drv... |
778 |
struct s2255_channel *channel = fh->channel; |
a19a5cd7b [media] s2255drv:... |
779 780 781 |
/* is it free? */ if (channel->resources) return 0; /* no, someone else uses it */ |
38f993ad8 V4L/DVB (8125): T... |
782 |
/* it's free, grab it */ |
fe85ce90a V4L/DVB: s2255drv... |
783 784 |
channel->resources = 1; fh->resources = 1; |
f78d92c9f V4L/DVB (8490): s... |
785 786 |
dprintk(1, "s2255: res: get "); |
38f993ad8 V4L/DVB (8125): T... |
787 788 |
return 1; } |
fe85ce90a V4L/DVB: s2255drv... |
789 |
static int res_locked(struct s2255_fh *fh) |
38f993ad8 V4L/DVB (8125): T... |
790 |
{ |
fe85ce90a V4L/DVB: s2255drv... |
791 |
return fh->channel->resources; |
38f993ad8 V4L/DVB (8125): T... |
792 |
} |
f78d92c9f V4L/DVB (8490): s... |
793 794 |
static int res_check(struct s2255_fh *fh) { |
fe85ce90a V4L/DVB: s2255drv... |
795 |
return fh->resources; |
f78d92c9f V4L/DVB (8490): s... |
796 |
} |
fe85ce90a V4L/DVB: s2255drv... |
797 |
static void res_free(struct s2255_fh *fh) |
38f993ad8 V4L/DVB (8125): T... |
798 |
{ |
fe85ce90a V4L/DVB: s2255drv... |
799 |
struct s2255_channel *channel = fh->channel; |
fe85ce90a V4L/DVB: s2255drv... |
800 801 |
channel->resources = 0; fh->resources = 0; |
38f993ad8 V4L/DVB (8125): T... |
802 803 804 |
dprintk(1, "res: put "); } |
5a34d9dfa 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 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 V4L/DVB (10309): ... |
833 |
usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); |
38f993ad8 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 [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 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 V4L/DVB: s2255drv... |
861 |
struct s2255_channel *channel = fh->channel; |
38f993ad8 V4L/DVB (8125): T... |
862 |
|
fe85ce90a V4L/DVB: s2255drv... |
863 864 |
f->fmt.pix.width = channel->width; f->fmt.pix.height = channel->height; |
38f993ad8 V4L/DVB (8125): T... |
865 |
f->fmt.pix.field = fh->vb_vidq.field; |
fe85ce90a 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 V4L/DVB (8125): T... |
868 |
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; |
3f8d6f73d V4L/DVB (8317): S... |
869 |
return 0; |
38f993ad8 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 V4L/DVB: s2255drv... |
879 |
struct s2255_channel *channel = fh->channel; |
38f993ad8 V4L/DVB (8125): T... |
880 |
int is_ntsc; |
38f993ad8 V4L/DVB (8125): T... |
881 |
is_ntsc = |
fe85ce90a V4L/DVB: s2255drv... |
882 |
(channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0; |
38f993ad8 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 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 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 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 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 V4L/DVB (8125): T... |
959 960 961 |
f->fmt.pix.width = LINE_SZ_1CIFS_PAL; field = V4L2_FIELD_TOP; } else { |
38f993ad8 V4L/DVB (8125): T... |
962 963 964 965 |
f->fmt.pix.width = LINE_SZ_1CIFS_PAL; field = V4L2_FIELD_TOP; } } |
38f993ad8 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 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 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 V4L/DVB: s2255drv... |
979 |
struct s2255_channel *channel = fh->channel; |
38f993ad8 V4L/DVB (8125): T... |
980 981 |
const struct s2255_fmt *fmt; struct videobuf_queue *q = &fh->vb_vidq; |
fe85ce90a V4L/DVB: s2255drv... |
982 |
struct s2255_mode mode; |
38f993ad8 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 V4L/DVB (8317): S... |
989 |
return ret; |
38f993ad8 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 V4L/DVB: s2255drv... |
1004 |
if (res_locked(fh)) { |
85b85482c V4L/DVB: s2255drv... |
1005 1006 |
dprintk(1, "%s: channel busy ", __func__); |
38f993ad8 V4L/DVB (8125): T... |
1007 1008 1009 |
ret = -EBUSY; goto out_s_fmt; } |
fe85ce90a 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 V4L/DVB (8125): T... |
1014 1015 |
fh->vb_vidq.field = f->fmt.pix.field; fh->type = f->type; |
fe85ce90a 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 V4L/DVB: s2255drv... |
1020 |
V4L2_MODE_HIGHQUALITY) |
fe85ce90a V4L/DVB: s2255drv... |
1021 |
mode.scale = SCALE_4CIFSI; |
85b85482c V4L/DVB: s2255drv... |
1022 |
else |
fe85ce90a V4L/DVB: s2255drv... |
1023 |
mode.scale = SCALE_4CIFS; |
7d8535329 V4L/DVB (11851): ... |
1024 |
} else |
fe85ce90a V4L/DVB: s2255drv... |
1025 |
mode.scale = SCALE_2CIFS; |
38f993ad8 V4L/DVB (8125): T... |
1026 1027 |
} else { |
fe85ce90a V4L/DVB: s2255drv... |
1028 |
mode.scale = SCALE_1CIFS; |
38f993ad8 V4L/DVB (8125): T... |
1029 |
} |
38f993ad8 V4L/DVB (8125): T... |
1030 |
/* color mode */ |
fe85ce90a V4L/DVB: s2255drv... |
1031 |
switch (channel->fmt->fourcc) { |
38f993ad8 V4L/DVB (8125): T... |
1032 |
case V4L2_PIX_FMT_GREY: |
fe85ce90a V4L/DVB: s2255drv... |
1033 1034 |
mode.color &= ~MASK_COLOR; mode.color |= COLOR_Y8; |
38f993ad8 V4L/DVB (8125): T... |
1035 |
break; |
14d962602 V4L/DVB (8752): s... |
1036 |
case V4L2_PIX_FMT_JPEG: |
d0ef8540f [media] s2255drv:... |
1037 |
case V4L2_PIX_FMT_MJPEG: |
fe85ce90a V4L/DVB: s2255drv... |
1038 1039 1040 |
mode.color &= ~MASK_COLOR; mode.color |= COLOR_JPG; mode.color |= (channel->jc.quality << 8); |
14d962602 V4L/DVB (8752): s... |
1041 |
break; |
38f993ad8 V4L/DVB (8125): T... |
1042 |
case V4L2_PIX_FMT_YUV422P: |
fe85ce90a V4L/DVB: s2255drv... |
1043 1044 |
mode.color &= ~MASK_COLOR; mode.color |= COLOR_YUVPL; |
38f993ad8 V4L/DVB (8125): T... |
1045 1046 1047 1048 |
break; case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_UYVY: default: |
fe85ce90a V4L/DVB: s2255drv... |
1049 1050 |
mode.color &= ~MASK_COLOR; mode.color |= COLOR_YUVPK; |
38f993ad8 V4L/DVB (8125): T... |
1051 1052 |
break; } |
fe85ce90a 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 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 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 V4L/DVB (11851): ... |
1127 |
case SCALE_4CIFSI: |
38f993ad8 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 V4L/DVB (11851): ... |
1145 |
case SCALE_4CIFSI: |
38f993ad8 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 V4L/DVB (8752): s... |
1162 |
if ((mode->color & MASK_COLOR) != COLOR_Y8) { |
38f993ad8 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 V4L/DVB: s2255drv... |
1176 |
static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode) |
38f993ad8 V4L/DVB (8125): T... |
1177 1178 1179 1180 |
{ struct device *dev = &sdev->udev->dev; dev_info(dev, "------------------------------------------------ "); |
85b85482c 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 V4L/DVB (8125): T... |
1187 1188 |
dev_info(dev, "bright: 0x%x ", mode->bright); |
38f993ad8 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 V4L/DVB: s2255drv... |
1201 |
static int s2255_set_mode(struct s2255_channel *channel, |
38f993ad8 V4L/DVB (8125): T... |
1202 1203 1204 |
struct s2255_mode *mode) { int res; |
3fa006052 V4L/DVB: s2255drv... |
1205 |
__le32 *buffer; |
38f993ad8 V4L/DVB (8125): T... |
1206 |
unsigned long chn_rev; |
fe85ce90a V4L/DVB: s2255drv... |
1207 |
struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); |
fe85ce90a V4L/DVB: s2255drv... |
1208 1209 1210 |
chn_rev = G_chnmap[channel->idx]; dprintk(3, "%s channel: %d ", __func__, channel->idx); |
22b88d48a V4L/DVB (8845): s... |
1211 |
/* if JPEG, set the quality */ |
5a34d9dfa 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 V4L/DVB: s2255drv... |
1216 |
mode->color |= (channel->jc.quality << 8); |
5a34d9dfa V4L/DVB: s2255drv... |
1217 |
} |
38f993ad8 V4L/DVB (8125): T... |
1218 |
/* save the mode */ |
fe85ce90a 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 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 V4L/DVB (8125): T... |
1229 1230 |
/* set the mode */ buffer[0] = IN_DATA_TOKEN; |
3fa006052 V4L/DVB: s2255drv... |
1231 |
buffer[1] = (__le32) cpu_to_le32(chn_rev); |
38f993ad8 V4L/DVB (8125): T... |
1232 |
buffer[2] = CMD_SET_MODE; |
fe85ce90a V4L/DVB: s2255drv... |
1233 1234 |
memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode)); channel->setmode_ready = 0; |
38f993ad8 V4L/DVB (8125): T... |
1235 1236 |
res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); if (debug) |
85b85482c V4L/DVB: s2255drv... |
1237 |
s2255_print_cfg(dev, mode); |
38f993ad8 V4L/DVB (8125): T... |
1238 |
kfree(buffer); |
38f993ad8 V4L/DVB (8125): T... |
1239 |
/* wait at least 3 frames before continuing */ |
14d962602 V4L/DVB (8752): s... |
1240 |
if (mode->restart) { |
fe85ce90a V4L/DVB: s2255drv... |
1241 1242 |
wait_event_timeout(channel->wait_setmode, (channel->setmode_ready != 0), |
14d962602 V4L/DVB (8752): s... |
1243 |
msecs_to_jiffies(S2255_SETMODE_TIMEOUT)); |
fe85ce90a V4L/DVB: s2255drv... |
1244 |
if (channel->setmode_ready != 1) { |
14d962602 V4L/DVB (8752): s... |
1245 1246 1247 1248 1249 |
printk(KERN_DEBUG "s2255: no set mode response "); res = -EFAULT; } } |
38f993ad8 V4L/DVB (8125): T... |
1250 |
/* clear the restart flag */ |
fe85ce90a V4L/DVB: s2255drv... |
1251 |
channel->mode.restart = 0; |
fe85ce90a V4L/DVB: s2255drv... |
1252 1253 |
dprintk(1, "%s chn %d, result: %d ", __func__, channel->idx, res); |
38f993ad8 V4L/DVB (8125): T... |
1254 1255 |
return res; } |
fe85ce90a V4L/DVB: s2255drv... |
1256 |
static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus) |
4de39f5d6 V4L/DVB: s2255drv... |
1257 1258 |
{ int res; |
3fa006052 V4L/DVB: s2255drv... |
1259 |
__le32 *buffer; |
4de39f5d6 V4L/DVB: s2255drv... |
1260 |
u32 chn_rev; |
fe85ce90a V4L/DVB: s2255drv... |
1261 |
struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); |
fe85ce90a V4L/DVB: s2255drv... |
1262 1263 1264 |
chn_rev = G_chnmap[channel->idx]; dprintk(4, "%s chan %d ", __func__, channel->idx); |
4de39f5d6 V4L/DVB: s2255drv... |
1265 1266 1267 1268 |
buffer = kzalloc(512, GFP_KERNEL); if (buffer == NULL) { dev_err(&dev->udev->dev, "out of mem "); |
4de39f5d6 V4L/DVB: s2255drv... |
1269 1270 1271 1272 |
return -ENOMEM; } /* form the get vid status command */ buffer[0] = IN_DATA_TOKEN; |
3fa006052 V4L/DVB: s2255drv... |
1273 |
buffer[1] = (__le32) cpu_to_le32(chn_rev); |
4de39f5d6 V4L/DVB: s2255drv... |
1274 1275 |
buffer[2] = CMD_STATUS; *pstatus = 0; |
fe85ce90a V4L/DVB: s2255drv... |
1276 |
channel->vidstatus_ready = 0; |
4de39f5d6 V4L/DVB: s2255drv... |
1277 1278 |
res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); kfree(buffer); |
fe85ce90a V4L/DVB: s2255drv... |
1279 1280 |
wait_event_timeout(channel->wait_vidstatus, (channel->vidstatus_ready != 0), |
4de39f5d6 V4L/DVB: s2255drv... |
1281 |
msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT)); |
fe85ce90a V4L/DVB: s2255drv... |
1282 |
if (channel->vidstatus_ready != 1) { |
4de39f5d6 V4L/DVB: s2255drv... |
1283 1284 1285 1286 |
printk(KERN_DEBUG "s2255: no vidstatus response "); res = -EFAULT; } |
fe85ce90a V4L/DVB: s2255drv... |
1287 |
*pstatus = channel->vidstatus; |
4de39f5d6 V4L/DVB: s2255drv... |
1288 1289 |
dprintk(4, "%s, vid status %d ", __func__, *pstatus); |
4de39f5d6 V4L/DVB: s2255drv... |
1290 1291 |
return res; } |
38f993ad8 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 V4L/DVB: s2255drv... |
1297 |
struct s2255_channel *channel = fh->channel; |
38f993ad8 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 V4L/DVB: s2255drv... |
1311 |
if (!res_get(fh)) { |
be9ed5117 V4L/DVB (10298): ... |
1312 1313 |
s2255_dev_err(&dev->udev->dev, "stream busy "); |
38f993ad8 V4L/DVB (8125): T... |
1314 1315 |
return -EBUSY; } |
fe85ce90a V4L/DVB: s2255drv... |
1316 1317 1318 1319 |
channel->last_frame = -1; channel->bad_payload = 0; channel->cur_frame = 0; channel->frame_count = 0; |
38f993ad8 V4L/DVB (8125): T... |
1320 |
for (j = 0; j < SYS_FRAMES; j++) { |
fe85ce90a V4L/DVB: s2255drv... |
1321 1322 |
channel->buffer.frame[j].ulState = S2255_READ_IDLE; channel->buffer.frame[j].cur_size = 0; |
38f993ad8 V4L/DVB (8125): T... |
1323 1324 1325 |
} res = videobuf_streamon(&fh->vb_vidq); if (res == 0) { |
fe85ce90a V4L/DVB: s2255drv... |
1326 1327 1328 1329 |
s2255_start_acquire(channel); channel->b_acquire = 1; } else res_free(fh); |
38f993ad8 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 V4L/DVB (8125): T... |
1335 |
struct s2255_fh *fh = priv; |
fe85ce90a V4L/DVB: s2255drv... |
1336 1337 |
dprintk(4, "%s , channel: %d", __func__, fh->channel->idx); |
38f993ad8 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 V4L/DVB: s2255drv... |
1348 |
s2255_stop_acquire(fh->channel); |
b7732a32a V4L/DVB (11392): ... |
1349 |
videobuf_streamoff(&fh->vb_vidq); |
fe85ce90a V4L/DVB: s2255drv... |
1350 |
res_free(fh); |
f78d92c9f V4L/DVB (8490): s... |
1351 |
return 0; |
38f993ad8 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 V4L/DVB: s2255drv... |
1357 |
struct s2255_mode mode; |
38f993ad8 V4L/DVB (8125): T... |
1358 1359 |
struct videobuf_queue *q = &fh->vb_vidq; int ret = 0; |
38f993ad8 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 V4L/DVB: s2255drv... |
1367 |
if (res_locked(fh)) { |
38f993ad8 V4L/DVB (8125): T... |
1368 1369 1370 1371 1372 |
dprintk(1, "can't change standard after started "); ret = -EBUSY; goto out_s_std; } |
fe85ce90a V4L/DVB: s2255drv... |
1373 |
mode = fh->channel->mode; |
38f993ad8 V4L/DVB (8125): T... |
1374 |
if (*i & V4L2_STD_NTSC) { |
e6b44bc52 V4L/DVB: s2255drv... |
1375 1376 1377 |
dprintk(4, "%s NTSC ", __func__); /* if changing format, reset frame decimation/intervals */ |
fe85ce90a V4L/DVB: s2255drv... |
1378 1379 1380 1381 |
if (mode.format != FORMAT_NTSC) { mode.restart = 1; mode.format = FORMAT_NTSC; mode.fdec = FDEC_1; |
e6b44bc52 V4L/DVB: s2255drv... |
1382 |
} |
38f993ad8 V4L/DVB (8125): T... |
1383 |
} else if (*i & V4L2_STD_PAL) { |
e6b44bc52 V4L/DVB: s2255drv... |
1384 1385 |
dprintk(4, "%s PAL ", __func__); |
fe85ce90a V4L/DVB: s2255drv... |
1386 1387 1388 1389 |
if (mode.format != FORMAT_PAL) { mode.restart = 1; mode.format = FORMAT_PAL; mode.fdec = FDEC_1; |
e6b44bc52 V4L/DVB: s2255drv... |
1390 |
} |
38f993ad8 V4L/DVB (8125): T... |
1391 1392 1393 |
} else { ret = -EINVAL; } |
fe85ce90a V4L/DVB: s2255drv... |
1394 1395 |
if (mode.restart) s2255_set_mode(fh->channel, &mode); |
38f993ad8 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 V4L/DVB: s2255drv... |
1411 1412 |
struct s2255_fh *fh = priv; struct s2255_dev *dev = fh->dev; |
fe85ce90a V4L/DVB: s2255drv... |
1413 |
struct s2255_channel *channel = fh->channel; |
4de39f5d6 V4L/DVB: s2255drv... |
1414 |
u32 status = 0; |
38f993ad8 V4L/DVB (8125): T... |
1415 1416 |
if (inp->index != 0) return -EINVAL; |
38f993ad8 V4L/DVB (8125): T... |
1417 1418 |
inp->type = V4L2_INPUT_TYPE_CAMERA; inp->std = S2255_NORMS; |
4de39f5d6 V4L/DVB: s2255drv... |
1419 1420 1421 |
inp->status = 0; if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) { int rc; |
fe85ce90a V4L/DVB: s2255drv... |
1422 |
rc = s2255_cmd_status(fh->channel, &status); |
4de39f5d6 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 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 V4L/DVB: s2255drv... |
1435 |
strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video", |
5a34d9dfa V4L/DVB: s2255drv... |
1436 1437 1438 |
sizeof(inp->name)); break; } |
3f8d6f73d V4L/DVB (8317): S... |
1439 |
return 0; |
38f993ad8 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 V4L/DVB: s2255drv... |
1458 |
struct s2255_fh *fh = priv; |
fe85ce90a V4L/DVB: s2255drv... |
1459 |
struct s2255_channel *channel = fh->channel; |
5a34d9dfa V4L/DVB: s2255drv... |
1460 |
struct s2255_dev *dev = fh->dev; |
2e70db9a4 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 V4L/DVB: s2255drv... |
1474 1475 1476 |
case V4L2_CID_PRIVATE_COLORFILTER: if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) return -EINVAL; |
fe85ce90a V4L/DVB: s2255drv... |
1477 |
if ((dev->pid == 0x2257) && (channel->idx > 1)) |
5a34d9dfa 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 V4L/DVB: s2255drv... |
1487 1488 1489 1490 1491 1492 |
default: return -EINVAL; } dprintk(4, "%s, id %d ", __func__, qc->id); return 0; |
38f993ad8 V4L/DVB (8125): T... |
1493 1494 1495 1496 1497 |
} static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { |
2e70db9a4 V4L/DVB: s2255drv... |
1498 |
struct s2255_fh *fh = priv; |
5a34d9dfa V4L/DVB: s2255drv... |
1499 |
struct s2255_dev *dev = fh->dev; |
fe85ce90a V4L/DVB: s2255drv... |
1500 |
struct s2255_channel *channel = fh->channel; |
2e70db9a4 V4L/DVB: s2255drv... |
1501 1502 |
switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: |
fe85ce90a V4L/DVB: s2255drv... |
1503 |
ctrl->value = channel->mode.bright; |
2e70db9a4 V4L/DVB: s2255drv... |
1504 1505 |
break; case V4L2_CID_CONTRAST: |
fe85ce90a V4L/DVB: s2255drv... |
1506 |
ctrl->value = channel->mode.contrast; |
2e70db9a4 V4L/DVB: s2255drv... |
1507 1508 |
break; case V4L2_CID_SATURATION: |
fe85ce90a V4L/DVB: s2255drv... |
1509 |
ctrl->value = channel->mode.saturation; |
2e70db9a4 V4L/DVB: s2255drv... |
1510 1511 |
break; case V4L2_CID_HUE: |
fe85ce90a V4L/DVB: s2255drv... |
1512 |
ctrl->value = channel->mode.hue; |
2e70db9a4 V4L/DVB: s2255drv... |
1513 |
break; |
5a34d9dfa V4L/DVB: s2255drv... |
1514 1515 1516 |
case V4L2_CID_PRIVATE_COLORFILTER: if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) return -EINVAL; |
fe85ce90a V4L/DVB: s2255drv... |
1517 |
if ((dev->pid == 0x2257) && (channel->idx > 1)) |
5a34d9dfa V4L/DVB: s2255drv... |
1518 |
return -EINVAL; |
fe85ce90a V4L/DVB: s2255drv... |
1519 |
ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16); |
5a34d9dfa V4L/DVB: s2255drv... |
1520 |
break; |
2e70db9a4 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 V4L/DVB (8125): T... |
1527 1528 1529 1530 1531 |
} static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { |
38f993ad8 V4L/DVB (8125): T... |
1532 |
struct s2255_fh *fh = priv; |
fe85ce90a 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 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 V4L/DVB: s2255drv... |
1542 |
mode.bright = ctrl->value; |
2e70db9a4 V4L/DVB: s2255drv... |
1543 1544 |
break; case V4L2_CID_CONTRAST: |
fe85ce90a V4L/DVB: s2255drv... |
1545 |
mode.contrast = ctrl->value; |
2e70db9a4 V4L/DVB: s2255drv... |
1546 1547 |
break; case V4L2_CID_HUE: |
fe85ce90a V4L/DVB: s2255drv... |
1548 |
mode.hue = ctrl->value; |
2e70db9a4 V4L/DVB: s2255drv... |
1549 1550 |
break; case V4L2_CID_SATURATION: |
fe85ce90a V4L/DVB: s2255drv... |
1551 |
mode.saturation = ctrl->value; |
2e70db9a4 V4L/DVB: s2255drv... |
1552 |
break; |
5a34d9dfa V4L/DVB: s2255drv... |
1553 1554 1555 |
case V4L2_CID_PRIVATE_COLORFILTER: if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) return -EINVAL; |
fe85ce90a V4L/DVB: s2255drv... |
1556 |
if ((dev->pid == 0x2257) && (channel->idx > 1)) |
5a34d9dfa V4L/DVB: s2255drv... |
1557 |
return -EINVAL; |
fe85ce90a V4L/DVB: s2255drv... |
1558 1559 |
mode.color &= ~MASK_INPUT_TYPE; mode.color |= ((ctrl->value ? 0 : 1) << 16); |
5a34d9dfa V4L/DVB: s2255drv... |
1560 |
break; |
2e70db9a4 V4L/DVB: s2255drv... |
1561 1562 |
default: return -EINVAL; |
38f993ad8 V4L/DVB (8125): T... |
1563 |
} |
fe85ce90a V4L/DVB: s2255drv... |
1564 |
mode.restart = 0; |
2e70db9a4 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 V4L/DVB: s2255drv... |
1569 |
s2255_set_mode(fh->channel, &mode); |
2e70db9a4 V4L/DVB: s2255drv... |
1570 |
return 0; |
38f993ad8 V4L/DVB (8125): T... |
1571 |
} |
22b88d48a 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 V4L/DVB: s2255drv... |
1576 1577 |
struct s2255_channel *channel = fh->channel; *jc = channel->jc; |
85b85482c V4L/DVB: s2255drv... |
1578 1579 |
dprintk(2, "%s: quality %d ", __func__, jc->quality); |
22b88d48a 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 V4L/DVB: s2255drv... |
1587 |
struct s2255_channel *channel = fh->channel; |
22b88d48a V4L/DVB (8845): s... |
1588 1589 |
if (jc->quality < 0 || jc->quality > 100) return -EINVAL; |
fe85ce90a V4L/DVB: s2255drv... |
1590 |
channel->jc.quality = jc->quality; |
85b85482c V4L/DVB: s2255drv... |
1591 1592 |
dprintk(2, "%s: quality %d ", __func__, jc->quality); |
22b88d48a V4L/DVB (8845): s... |
1593 1594 |
return 0; } |
7d8535329 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 V4L/DVB: s2255drv... |
1600 |
__u32 def_num, def_dem; |
fe85ce90a V4L/DVB: s2255drv... |
1601 |
struct s2255_channel *channel = fh->channel; |
7d8535329 V4L/DVB (11851): ... |
1602 1603 |
if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; |
e6b44bc52 V4L/DVB: s2255drv... |
1604 1605 |
memset(sp, 0, sizeof(struct v4l2_streamparm)); sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; |
fe85ce90a 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 V4L/DVB: s2255drv... |
1609 |
sp->parm.capture.timeperframe.denominator = def_dem; |
fe85ce90a V4L/DVB: s2255drv... |
1610 |
switch (channel->mode.fdec) { |
e6b44bc52 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 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 V4L/DVB: s2255drv... |
1637 1638 |
struct s2255_channel *channel = fh->channel; struct s2255_mode mode; |
e6b44bc52 V4L/DVB: s2255drv... |
1639 1640 |
int fdec = FDEC_1; __u32 def_num, def_dem; |
7d8535329 V4L/DVB (11851): ... |
1641 1642 |
if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; |
fe85ce90a V4L/DVB: s2255drv... |
1643 |
mode = channel->mode; |
e6b44bc52 V4L/DVB: s2255drv... |
1644 |
/* high quality capture mode requires a stream restart */ |
fe85ce90a V4L/DVB: s2255drv... |
1645 1646 |
if (channel->cap_parm.capturemode != sp->parm.capture.capturemode && res_locked(fh)) |
e6b44bc52 V4L/DVB: s2255drv... |
1647 |
return -EBUSY; |
fe85ce90a V4L/DVB: s2255drv... |
1648 1649 |
def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000; def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000; |
e6b44bc52 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 V4L/DVB: s2255drv... |
1664 |
mode.fdec = fdec; |
e6b44bc52 V4L/DVB: s2255drv... |
1665 |
sp->parm.capture.timeperframe.denominator = def_dem; |
fe85ce90a V4L/DVB: s2255drv... |
1666 |
s2255_set_mode(channel, &mode); |
e6b44bc52 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 V4L/DVB (11851): ... |
1675 |
|
e6b44bc52 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 V4L/DVB (11851): ... |
1712 1713 |
return 0; } |
e6b44bc52 V4L/DVB: s2255drv... |
1714 |
|
bec43661b V4L/DVB (10135): ... |
1715 |
static int s2255_open(struct file *file) |
38f993ad8 V4L/DVB (8125): T... |
1716 |
{ |
63b0d5ad2 V4L/DVB (13554a):... |
1717 |
struct video_device *vdev = video_devdata(file); |
fe85ce90a V4L/DVB: s2255drv... |
1718 1719 |
struct s2255_channel *channel = video_drvdata(file); struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev); |
38f993ad8 V4L/DVB (8125): T... |
1720 |
struct s2255_fh *fh; |
63b0d5ad2 V4L/DVB (13554a):... |
1721 |
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
14d962602 V4L/DVB (8752): s... |
1722 |
int state; |
50462eb06 V4L/DVB (13555): ... |
1723 1724 1725 |
dprintk(1, "s2255: open called (dev=%s) ", video_device_node_name(vdev)); |
ff7e22dfa 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 V4L/DVB (8752): s... |
1736 |
return -ENODEV; |
14d962602 V4L/DVB (8752): s... |
1737 |
case S2255_FW_FAILED: |
be9ed5117 V4L/DVB (10298): ... |
1738 1739 1740 |
s2255_dev_err(&dev->udev->dev, "firmware load failed. retrying. "); |
14d962602 V4L/DVB (8752): s... |
1741 |
s2255_fwload_start(dev, 1); |
38f993ad8 V4L/DVB (8125): T... |
1742 |
wait_event_timeout(dev->fw_data->wait_fw, |
14d962602 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 V4L/DVB (8125): T... |
1747 |
msecs_to_jiffies(S2255_LOAD_TIMEOUT)); |
ff7e22dfa V4L/DVB: s2255drv... |
1748 1749 |
/* state may have changed, re-read */ state = atomic_read(&dev->fw_data->fw_state); |
14d962602 V4L/DVB (8752): s... |
1750 1751 1752 |
break; case S2255_FW_NOTLOADED: case S2255_FW_LOADED_DSPWAIT: |
38f993ad8 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 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 V4L/DVB: s2255drv... |
1762 |
msecs_to_jiffies(S2255_LOAD_TIMEOUT)); |
ff7e22dfa V4L/DVB: s2255drv... |
1763 1764 |
/* state may have changed, re-read */ state = atomic_read(&dev->fw_data->fw_state); |
14d962602 V4L/DVB (8752): s... |
1765 1766 1767 1768 1769 |
break; case S2255_FW_SUCCESS: default: break; } |
ff7e22dfa 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 V4L/DVB: s2255drv... |
1777 |
mutex_unlock(&dev->open_lock); |
ff7e22dfa V4L/DVB: s2255drv... |
1778 1779 1780 1781 |
return -ENODEV; case S2255_FW_DISCONNECTING: printk(KERN_INFO "%s: disconnecting ", __func__); |
eb78deecb V4L/DVB: s2255drv... |
1782 |
mutex_unlock(&dev->open_lock); |
ff7e22dfa 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 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 V4L/DVB: s2255drv... |
1798 1799 1800 1801 |
return -EAGAIN; default: printk(KERN_INFO "%s: unknown state ", __func__); |
eb78deecb V4L/DVB: s2255drv... |
1802 |
mutex_unlock(&dev->open_lock); |
ff7e22dfa V4L/DVB: s2255drv... |
1803 |
return -EFAULT; |
38f993ad8 V4L/DVB (8125): T... |
1804 |
} |
eb78deecb V4L/DVB: s2255drv... |
1805 |
mutex_unlock(&dev->open_lock); |
38f993ad8 V4L/DVB (8125): T... |
1806 1807 |
/* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
a5ef91c9a V4L/DVB: s2255drv... |
1808 |
if (NULL == fh) |
38f993ad8 V4L/DVB (8125): T... |
1809 |
return -ENOMEM; |
38f993ad8 V4L/DVB (8125): T... |
1810 1811 1812 |
file->private_data = fh; fh->dev = dev; fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
fe85ce90a 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 V4L/DVB (8752): s... |
1819 |
} |
85b85482c V4L/DVB: s2255drv... |
1820 1821 |
dprintk(1, "%s: dev=%s type=%s ", __func__, |
ff7e22dfa V4L/DVB: s2255drv... |
1822 |
video_device_node_name(vdev), v4l2_type_names[type]); |
85b85482c V4L/DVB: s2255drv... |
1823 1824 |
dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx ", __func__, |
38f993ad8 V4L/DVB (8125): T... |
1825 |
(unsigned long)fh, (unsigned long)dev, |
fe85ce90a V4L/DVB: s2255drv... |
1826 |
(unsigned long)&channel->vidq); |
85b85482c V4L/DVB: s2255drv... |
1827 1828 |
dprintk(4, "%s: list_empty active=%d ", __func__, |
fe85ce90a V4L/DVB: s2255drv... |
1829 |
list_empty(&channel->vidq.active)); |
38f993ad8 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 [media] s2255drv:... |
1834 1835 |
sizeof(struct s2255_buffer), fh, vdev->lock); |
38f993ad8 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 V4L/DVB (8125): T... |
1847 1848 |
if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) return POLLERR; |
38f993ad8 V4L/DVB (8125): T... |
1849 1850 1851 |
rc = videobuf_poll_stream(file, &fh->vb_vidq, wait); return rc; } |
d62e85a09 V4L/DVB: s2255drv... |
1852 |
static void s2255_destroy(struct s2255_dev *dev) |
38f993ad8 V4L/DVB (8125): T... |
1853 |
{ |
38f993ad8 V4L/DVB (8125): T... |
1854 1855 |
/* board shutdown stops the read pipe if it is running */ s2255_board_shutdown(dev); |
38f993ad8 V4L/DVB (8125): T... |
1856 |
/* make sure firmware still not trying to load */ |
f78d92c9f V4L/DVB (8490): s... |
1857 |
del_timer(&dev->timer); /* only started in .probe and .open */ |
38f993ad8 V4L/DVB (8125): T... |
1858 |
if (dev->fw_data->fw_urb) { |
38f993ad8 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 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 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 V4L/DVB (8125): T... |
1871 |
usb_put_dev(dev->udev); |
fe85ce90a V4L/DVB: s2255drv... |
1872 |
v4l2_device_unregister(&dev->v4l2_dev); |
38f993ad8 V4L/DVB (8125): T... |
1873 |
dprintk(1, "%s", __func__); |
b7732a32a V4L/DVB (11392): ... |
1874 |
kfree(dev); |
38f993ad8 V4L/DVB (8125): T... |
1875 |
} |
ff7e22dfa V4L/DVB: s2255drv... |
1876 |
static int s2255_release(struct file *file) |
38f993ad8 V4L/DVB (8125): T... |
1877 1878 1879 |
{ struct s2255_fh *fh = file->private_data; struct s2255_dev *dev = fh->dev; |
50462eb06 V4L/DVB (13555): ... |
1880 |
struct video_device *vdev = video_devdata(file); |
fe85ce90a V4L/DVB: s2255drv... |
1881 |
struct s2255_channel *channel = fh->channel; |
38f993ad8 V4L/DVB (8125): T... |
1882 1883 |
if (!dev) return -ENODEV; |
f78d92c9f V4L/DVB (8490): s... |
1884 1885 |
/* turn off stream */ if (res_check(fh)) { |
fe85ce90a V4L/DVB: s2255drv... |
1886 1887 |
if (channel->b_acquire) s2255_stop_acquire(fh->channel); |
f78d92c9f V4L/DVB (8490): s... |
1888 |
videobuf_streamoff(&fh->vb_vidq); |
fe85ce90a V4L/DVB: s2255drv... |
1889 |
res_free(fh); |
f78d92c9f V4L/DVB (8490): s... |
1890 |
} |
38f993ad8 V4L/DVB (8125): T... |
1891 |
videobuf_mmap_free(&fh->vb_vidq); |
ff7e22dfa V4L/DVB: s2255drv... |
1892 1893 |
dprintk(1, "%s (dev=%s) ", __func__, video_device_node_name(vdev)); |
f78d92c9f V4L/DVB (8490): s... |
1894 |
kfree(fh); |
38f993ad8 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 V4L/DVB: s2255drv... |
1905 1906 |
dprintk(4, "%s, vma=0x%08lx ", __func__, (unsigned long)vma); |
38f993ad8 V4L/DVB (8125): T... |
1907 |
ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); |
85b85482c V4L/DVB: s2255drv... |
1908 1909 |
dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d ", __func__, |
38f993ad8 V4L/DVB (8125): T... |
1910 1911 |
(unsigned long)vma->vm_start, (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret); |
38f993ad8 V4L/DVB (8125): T... |
1912 1913 |
return ret; } |
bec43661b V4L/DVB (10135): ... |
1914 |
static const struct v4l2_file_operations s2255_fops_v4l = { |
38f993ad8 V4L/DVB (8125): T... |
1915 1916 |
.owner = THIS_MODULE, .open = s2255_open, |
ff7e22dfa V4L/DVB: s2255drv... |
1917 |
.release = s2255_release, |
38f993ad8 V4L/DVB (8125): T... |
1918 |
.poll = s2255_poll, |
a19a5cd7b [media] s2255drv:... |
1919 |
.unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ |
38f993ad8 V4L/DVB (8125): T... |
1920 |
.mmap = s2255_mmap_v4l, |
38f993ad8 V4L/DVB (8125): T... |
1921 |
}; |
a399810ca V4L/DVB (8482): v... |
1922 |
static const struct v4l2_ioctl_ops s2255_ioctl_ops = { |
5a34d9dfa V4L/DVB: s2255drv... |
1923 |
.vidioc_querymenu = vidioc_querymenu, |
38f993ad8 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 V4L/DVB (8845): s... |
1942 1943 |
.vidioc_s_jpegcomp = vidioc_s_jpegcomp, .vidioc_g_jpegcomp = vidioc_g_jpegcomp, |
7d8535329 V4L/DVB (11851): ... |
1944 1945 |
.vidioc_s_parm = vidioc_s_parm, .vidioc_g_parm = vidioc_g_parm, |
e6b44bc52 V4L/DVB: s2255drv... |
1946 |
.vidioc_enum_frameintervals = vidioc_enum_frameintervals, |
a399810ca V4L/DVB (8482): v... |
1947 |
}; |
ff7e22dfa V4L/DVB: s2255drv... |
1948 1949 |
static void s2255_video_device_release(struct video_device *vdev) { |
fe85ce90a 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 V4L/DVB: s2255drv... |
1955 |
s2255_destroy(dev); |
ff7e22dfa V4L/DVB: s2255drv... |
1956 1957 |
return; } |
a399810ca V4L/DVB (8482): v... |
1958 1959 |
static struct video_device template = { .name = "s2255v", |
a399810ca V4L/DVB (8482): v... |
1960 1961 |
.fops = &s2255_fops_v4l, .ioctl_ops = &s2255_ioctl_ops, |
ff7e22dfa V4L/DVB: s2255drv... |
1962 |
.release = s2255_video_device_release, |
38f993ad8 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 V4L/DVB: s2255drv... |
1972 |
struct s2255_channel *channel; |
65c6edb30 V4L/DVB: s2255drv... |
1973 1974 1975 |
ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev); if (ret) return ret; |
38f993ad8 V4L/DVB (8125): T... |
1976 |
/* initialize all video 4 linux */ |
38f993ad8 V4L/DVB (8125): T... |
1977 1978 |
/* register 4 video devices */ for (i = 0; i < MAX_CHANNELS; i++) { |
fe85ce90a V4L/DVB: s2255drv... |
1979 1980 1981 |
channel = &dev->channel[i]; INIT_LIST_HEAD(&channel->vidq.active); channel->vidq.dev = dev; |
38f993ad8 V4L/DVB (8125): T... |
1982 |
/* register 4 video devices */ |
fe85ce90a V4L/DVB: s2255drv... |
1983 |
channel->vdev = template; |
a19a5cd7b [media] s2255drv:... |
1984 |
channel->vdev.lock = &dev->lock; |
fe85ce90a V4L/DVB: s2255drv... |
1985 1986 |
channel->vdev.v4l2_dev = &dev->v4l2_dev; video_set_drvdata(&channel->vdev, channel); |
38f993ad8 V4L/DVB (8125): T... |
1987 |
if (video_nr == -1) |
fe85ce90a V4L/DVB: s2255drv... |
1988 |
ret = video_register_device(&channel->vdev, |
38f993ad8 V4L/DVB (8125): T... |
1989 1990 1991 |
VFL_TYPE_GRABBER, video_nr); else |
fe85ce90a V4L/DVB: s2255drv... |
1992 |
ret = video_register_device(&channel->vdev, |
38f993ad8 V4L/DVB (8125): T... |
1993 1994 |
VFL_TYPE_GRABBER, cur_nr + i); |
fe85ce90a V4L/DVB: s2255drv... |
1995 |
|
3a67b5cc6 V4L/DVB: s2255drv... |
1996 |
if (ret) { |
38f993ad8 V4L/DVB (8125): T... |
1997 1998 1999 |
dev_err(&dev->udev->dev, "failed to register video device! "); |
3a67b5cc6 V4L/DVB: s2255drv... |
2000 |
break; |
38f993ad8 V4L/DVB (8125): T... |
2001 |
} |
fe85ce90a V4L/DVB: s2255drv... |
2002 |
atomic_inc(&dev->num_channels); |
65c6edb30 V4L/DVB: s2255drv... |
2003 2004 |
v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s ", |
fe85ce90a V4L/DVB: s2255drv... |
2005 |
video_device_node_name(&channel->vdev)); |
3a67b5cc6 V4L/DVB: s2255drv... |
2006 |
|
38f993ad8 V4L/DVB (8125): T... |
2007 |
} |
64dc3c1a9 [media] Stop usin... |
2008 2009 2010 |
printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %s ", S2255_VERSION); |
3a67b5cc6 V4L/DVB: s2255drv... |
2011 |
/* if no channels registered, return error and probe will fail*/ |
fe85ce90a V4L/DVB: s2255drv... |
2012 |
if (atomic_read(&dev->num_channels) == 0) { |
65c6edb30 V4L/DVB: s2255drv... |
2013 |
v4l2_device_unregister(&dev->v4l2_dev); |
3a67b5cc6 V4L/DVB: s2255drv... |
2014 |
return ret; |
65c6edb30 V4L/DVB: s2255drv... |
2015 |
} |
fe85ce90a V4L/DVB: s2255drv... |
2016 |
if (atomic_read(&dev->num_channels) != MAX_CHANNELS) |
3a67b5cc6 V4L/DVB: s2255drv... |
2017 2018 2019 |
printk(KERN_WARNING "s2255: Not all channels available. "); return 0; |
38f993ad8 V4L/DVB (8125): T... |
2020 |
} |
38f993ad8 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 V4L/DVB (8752): s... |
2027 |
* bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME) |
38f993ad8 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 V4L/DVB (8125): T... |
2034 2035 |
char *pdest; u32 offset = 0; |
14d962602 V4L/DVB (8752): s... |
2036 |
int bframe = 0; |
38f993ad8 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 V4L/DVB: s2255drv... |
2043 |
struct s2255_channel *channel; |
38f993ad8 V4L/DVB (8125): T... |
2044 2045 |
dprintk(100, "buffer to user "); |
fe85ce90a V4L/DVB: s2255drv... |
2046 2047 2048 |
channel = &dev->channel[dev->cc]; idx = channel->cur_frame; frm = &channel->buffer.frame[idx]; |
14d962602 V4L/DVB (8752): s... |
2049 2050 2051 |
if (frm->ulState == S2255_READ_IDLE) { int jj; unsigned int cc; |
3fa006052 V4L/DVB: s2255drv... |
2052 |
__le32 *pdword; /*data from dsp is little endian */ |
14d962602 V4L/DVB (8752): s... |
2053 2054 2055 |
int payload; /* search for marker codes */ pdata = (unsigned char *)pipe_info->transfer_buffer; |
3fa006052 V4L/DVB: s2255drv... |
2056 |
pdword = (__le32 *)pdata; |
14d962602 V4L/DVB (8752): s... |
2057 |
for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) { |
3fa006052 V4L/DVB: s2255drv... |
2058 |
switch (*pdword) { |
14d962602 V4L/DVB (8752): s... |
2059 |
case S2255_MARKER_FRAME: |
14d962602 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 V4L/DVB: s2255drv... |
2075 |
channel = &dev->channel[dev->cc]; |
14d962602 V4L/DVB (8752): s... |
2076 |
payload = pdword[3]; |
fe85ce90a V4L/DVB: s2255drv... |
2077 2078 |
if (payload > channel->req_image_size) { channel->bad_payload++; |
14d962602 V4L/DVB (8752): s... |
2079 2080 2081 |
/* discard the bad frame */ return -EINVAL; } |
fe85ce90a V4L/DVB: s2255drv... |
2082 2083 |
channel->pkt_size = payload; channel->jpg_size = pdword[4]; |
14d962602 V4L/DVB (8752): s... |
2084 2085 |
break; case S2255_MARKER_RESPONSE: |
fe85ce90a V4L/DVB: s2255drv... |
2086 |
|
14d962602 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 V4L/DVB (13241): ... |
2092 |
if (cc >= MAX_CHANNELS) |
14d962602 V4L/DVB (8752): s... |
2093 |
break; |
fe85ce90a V4L/DVB: s2255drv... |
2094 |
channel = &dev->channel[cc]; |
14d962602 V4L/DVB (8752): s... |
2095 |
switch (pdword[2]) { |
abce21f40 V4L/DVB (11605): ... |
2096 |
case S2255_RESPONSE_SETMODE: |
14d962602 V4L/DVB (8752): s... |
2097 2098 |
/* check if channel valid */ /* set mode ready */ |
fe85ce90a V4L/DVB: s2255drv... |
2099 2100 |
channel->setmode_ready = 1; wake_up(&channel->wait_setmode); |
14d962602 V4L/DVB (8752): s... |
2101 2102 |
dprintk(5, "setmode ready %d ", cc); |
38f993ad8 V4L/DVB (8125): T... |
2103 |
break; |
abce21f40 V4L/DVB (11605): ... |
2104 |
case S2255_RESPONSE_FW: |
14d962602 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 V4L/DVB: s2255drv... |
2115 |
case S2255_RESPONSE_STATUS: |
fe85ce90a V4L/DVB: s2255drv... |
2116 2117 2118 |
channel->vidstatus = pdword[3]; channel->vidstatus_ready = 1; wake_up(&channel->wait_vidstatus); |
4de39f5d6 V4L/DVB: s2255drv... |
2119 2120 2121 2122 |
dprintk(5, "got vidstatus %x chan %d ", pdword[3], cc); break; |
14d962602 V4L/DVB (8752): s... |
2123 |
default: |
af901ca18 tree-wide: fix as... |
2124 2125 |
printk(KERN_INFO "s2255 unknown resp "); |
38f993ad8 V4L/DVB (8125): T... |
2126 |
} |
14d962602 V4L/DVB (8752): s... |
2127 |
default: |
38f993ad8 V4L/DVB (8125): T... |
2128 |
pdata++; |
14d962602 V4L/DVB (8752): s... |
2129 |
break; |
38f993ad8 V4L/DVB (8125): T... |
2130 |
} |
14d962602 V4L/DVB (8752): s... |
2131 2132 2133 2134 2135 |
if (bframe) break; } /* for */ if (!bframe) return -EINVAL; |
38f993ad8 V4L/DVB (8125): T... |
2136 |
} |
fe85ce90a V4L/DVB: s2255drv... |
2137 2138 2139 |
channel = &dev->channel[dev->cc]; idx = channel->cur_frame; frm = &channel->buffer.frame[idx]; |
14d962602 V4L/DVB (8752): s... |
2140 |
/* search done. now find out if should be acquiring on this channel */ |
fe85ce90a V4L/DVB: s2255drv... |
2141 |
if (!channel->b_acquire) { |
14d962602 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 V4L/DVB (8125): T... |
2145 |
} |
14d962602 V4L/DVB (8752): s... |
2146 2147 2148 |
if (frm->ulState == S2255_READ_IDLE) { frm->ulState = S2255_READ_FRAME; frm->cur_size = 0; |
38f993ad8 V4L/DVB (8125): T... |
2149 |
} |
14d962602 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 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 V4L/DVB (8752): s... |
2159 |
copy_size = (pipe_info->cur_transfer_size - offset); |
38f993ad8 V4L/DVB (8125): T... |
2160 |
|
fe85ce90a V4L/DVB: s2255drv... |
2161 |
size = channel->pkt_size - PREFIX_SIZE; |
38f993ad8 V4L/DVB (8125): T... |
2162 |
|
14d962602 V4L/DVB (8752): s... |
2163 |
/* sanity check on pdest */ |
fe85ce90a V4L/DVB: s2255drv... |
2164 |
if ((copy_size + frm->cur_size) < channel->req_image_size) |
14d962602 V4L/DVB (8752): s... |
2165 |
memcpy(pdest, psrc, copy_size); |
38f993ad8 V4L/DVB (8125): T... |
2166 |
|
38f993ad8 V4L/DVB (8125): T... |
2167 |
frm->cur_size += copy_size; |
14d962602 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 V4L/DVB (8125): T... |
2172 2173 |
dprintk(2, "****************[%d]Buffer[%d]full************* ", |
fe85ce90a V4L/DVB: s2255drv... |
2174 2175 2176 |
dev->cc, idx); channel->last_frame = channel->cur_frame; channel->cur_frame++; |
38f993ad8 V4L/DVB (8125): T... |
2177 |
/* end of system frame ring buffer, start at zero */ |
fe85ce90a V4L/DVB: s2255drv... |
2178 2179 2180 |
if ((channel->cur_frame == SYS_FRAMES) || (channel->cur_frame == channel->buffer.dwFrames)) channel->cur_frame = 0; |
14d962602 V4L/DVB (8752): s... |
2181 |
/* frame ready */ |
fe85ce90a V4L/DVB: s2255drv... |
2182 2183 2184 |
if (channel->b_acquire) s2255_got_frame(channel, channel->jpg_size); channel->frame_count++; |
14d962602 V4L/DVB (8752): s... |
2185 2186 |
frm->ulState = S2255_READ_IDLE; frm->cur_size = 0; |
38f993ad8 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 V4L/DVB (8752): s... |
2207 2208 2209 |
if (res != 0) dprintk(4, "s2255: read callback failed "); |
38f993ad8 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 V4L/DVB: s2255drv... |
2262 |
static int s2255_create_sys_buffers(struct s2255_channel *channel) |
38f993ad8 V4L/DVB (8125): T... |
2263 2264 2265 2266 2267 |
{ unsigned long i; unsigned long reqsize; dprintk(1, "create sys buffers "); |
fe85ce90a V4L/DVB: s2255drv... |
2268 |
channel->buffer.dwFrames = SYS_FRAMES; |
38f993ad8 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 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 V4L/DVB (8125): T... |
2284 2285 |
printk(KERN_INFO "out of memory. using less frames "); |
fe85ce90a V4L/DVB: s2255drv... |
2286 |
channel->buffer.dwFrames = i; |
38f993ad8 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 V4L/DVB: s2255drv... |
2293 2294 |
channel->buffer.frame[i].ulState = 0; channel->buffer.frame[i].cur_size = 0; |
38f993ad8 V4L/DVB (8125): T... |
2295 |
} |
fe85ce90a V4L/DVB: s2255drv... |
2296 2297 |
channel->cur_frame = 0; channel->last_frame = -1; |
38f993ad8 V4L/DVB (8125): T... |
2298 2299 |
return 0; } |
fe85ce90a V4L/DVB: s2255drv... |
2300 |
static int s2255_release_sys_buffers(struct s2255_channel *channel) |
38f993ad8 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 V4L/DVB: s2255drv... |
2306 |
if (channel->buffer.frame[i].lpvbits) { |
38f993ad8 V4L/DVB (8125): T... |
2307 2308 |
dprintk(1, "vfree %p ", |
fe85ce90a V4L/DVB: s2255drv... |
2309 2310 |
channel->buffer.frame[i].lpvbits); vfree(channel->buffer.frame[i].lpvbits); |
38f993ad8 V4L/DVB (8125): T... |
2311 |
} |
fe85ce90a V4L/DVB: s2255drv... |
2312 |
channel->buffer.frame[i].lpvbits = NULL; |
38f993ad8 V4L/DVB (8125): T... |
2313 2314 2315 2316 2317 2318 |
} return 0; } static int s2255_board_init(struct s2255_dev *dev) { |
38f993ad8 V4L/DVB (8125): T... |
2319 2320 |
struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT; int fw_ver; |
ab85c6a33 V4L/DVB: s2255drv... |
2321 2322 |
int j; struct s2255_pipeinfo *pipe = &dev->pipe; |
38f993ad8 V4L/DVB (8125): T... |
2323 |
dprintk(4, "board init: %p", dev); |
ab85c6a33 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 V4L/DVB (8125): T... |
2335 |
} |
38f993ad8 V4L/DVB (8125): T... |
2336 2337 |
/* query the firmware */ fw_ver = s2255_get_fx2fw(dev); |
8a8cc952d [media] s2255drv:... |
2338 2339 |
printk(KERN_INFO "s2255: usb firmware version %d.%d ", |
abce21f40 V4L/DVB (11605): ... |
2340 2341 2342 2343 |
(fw_ver >> 8) & 0xff, fw_ver & 0xff); if (fw_ver < S2255_CUR_USB_FWVER) |
8a8cc952d [media] s2255drv:... |
2344 2345 |
printk(KERN_INFO "s2255: newer USB firmware available "); |
38f993ad8 V4L/DVB (8125): T... |
2346 2347 |
for (j = 0; j < MAX_CHANNELS; j++) { |
fe85ce90a V4L/DVB: s2255drv... |
2348 2349 2350 |
struct s2255_channel *channel = &dev->channel[j]; channel->b_acquire = 0; channel->mode = mode_def; |
5a34d9dfa V4L/DVB: s2255drv... |
2351 |
if (dev->pid == 0x2257 && j > 1) |
fe85ce90a 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 V4L/DVB (8125): T... |
2360 |
/* create the system buffers */ |
fe85ce90a V4L/DVB: s2255drv... |
2361 |
s2255_create_sys_buffers(channel); |
38f993ad8 V4L/DVB (8125): T... |
2362 2363 2364 |
} /* start read pipe */ s2255_start_readpipe(dev); |
85b85482c V4L/DVB: s2255drv... |
2365 2366 |
dprintk(1, "%s: success ", __func__); |
38f993ad8 V4L/DVB (8125): T... |
2367 2368 2369 2370 2371 2372 |
return 0; } static int s2255_board_shutdown(struct s2255_dev *dev) { u32 i; |
85b85482c V4L/DVB: s2255drv... |
2373 |
dprintk(1, "%s: dev: %p", __func__, dev); |
38f993ad8 V4L/DVB (8125): T... |
2374 2375 |
for (i = 0; i < MAX_CHANNELS; i++) { |
fe85ce90a V4L/DVB: s2255drv... |
2376 2377 |
if (dev->channel[i].b_acquire) s2255_stop_acquire(&dev->channel[i]); |
38f993ad8 V4L/DVB (8125): T... |
2378 |
} |
38f993ad8 V4L/DVB (8125): T... |
2379 |
s2255_stop_readpipe(dev); |
38f993ad8 V4L/DVB (8125): T... |
2380 |
for (i = 0; i < MAX_CHANNELS; i++) |
fe85ce90a V4L/DVB: s2255drv... |
2381 |
s2255_release_sys_buffers(&dev->channel[i]); |
ab85c6a33 V4L/DVB: s2255drv... |
2382 2383 |
/* release transfer buffer */ kfree(dev->pipe.transfer_buffer); |
38f993ad8 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 V4L/DVB (8125): T... |
2393 |
pipe_info = purb->context; |
85b85482c V4L/DVB: s2255drv... |
2394 2395 |
dprintk(100, "%s: urb:%p, status %d ", __func__, purb, |
38f993ad8 V4L/DVB (8125): T... |
2396 2397 |
purb->status); if (pipe_info == NULL) { |
be9ed5117 V4L/DVB (10298): ... |
2398 2399 |
dev_err(&purb->dev->dev, "no context! "); |
38f993ad8 V4L/DVB (8125): T... |
2400 2401 2402 2403 2404 |
return; } dev = pipe_info->dev; if (dev == NULL) { |
be9ed5117 V4L/DVB (10298): ... |
2405 2406 |
dev_err(&purb->dev->dev, "no context! "); |
38f993ad8 V4L/DVB (8125): T... |
2407 2408 2409 |
return; } status = purb->status; |
b02064cae V4L/DVB (11738): ... |
2410 2411 |
/* if shutting down, do not resubmit, exit immediately */ if (status == -ESHUTDOWN) { |
85b85482c V4L/DVB: s2255drv... |
2412 2413 |
dprintk(2, "%s: err shutdown ", __func__); |
b02064cae V4L/DVB (11738): ... |
2414 |
pipe_info->err_count++; |
38f993ad8 V4L/DVB (8125): T... |
2415 2416 2417 2418 |
return; } if (pipe_info->state == 0) { |
85b85482c V4L/DVB: s2255drv... |
2419 |
dprintk(2, "%s: exiting USB pipe", __func__); |
38f993ad8 V4L/DVB (8125): T... |
2420 2421 |
return; } |
b02064cae V4L/DVB (11738): ... |
2422 2423 2424 2425 |
if (status == 0) s2255_read_video_callback(dev, pipe_info); else { pipe_info->err_count++; |
85b85482c V4L/DVB: s2255drv... |
2426 2427 |
dprintk(1, "%s: failed URB %d ", __func__, status); |
b02064cae V4L/DVB (11738): ... |
2428 |
} |
38f993ad8 V4L/DVB (8125): T... |
2429 |
|
38f993ad8 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 [media] s2255drv:... |
2439 |
if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) { |
38f993ad8 V4L/DVB (8125): T... |
2440 2441 |
dev_err(&dev->udev->dev, "error submitting urb "); |
38f993ad8 V4L/DVB (8125): T... |
2442 2443 |
} } else { |
85b85482c V4L/DVB: s2255drv... |
2444 2445 |
dprintk(2, "%s :complete state 0 ", __func__); |
38f993ad8 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 V4L/DVB: s2255drv... |
2454 |
struct s2255_pipeinfo *pipe_info = &dev->pipe; |
38f993ad8 V4L/DVB (8125): T... |
2455 |
pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); |
85b85482c V4L/DVB: s2255drv... |
2456 2457 |
dprintk(2, "%s: IN %d ", __func__, dev->read_endpoint); |
ab85c6a33 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 V4L/DVB (8125): T... |
2466 |
} |
ab85c6a33 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 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 V4L/DVB (8125): T... |
2479 2480 2481 2482 |
return 0; } /* starts acquisition process */ |
fe85ce90a V4L/DVB: s2255drv... |
2483 |
static int s2255_start_acquire(struct s2255_channel *channel) |
38f993ad8 V4L/DVB (8125): T... |
2484 2485 2486 2487 2488 |
{ unsigned char *buffer; int res; unsigned long chn_rev; int j; |
fe85ce90a V4L/DVB: s2255drv... |
2489 2490 |
struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); chn_rev = G_chnmap[channel->idx]; |
38f993ad8 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 V4L/DVB: s2255drv... |
2497 2498 2499 |
channel->last_frame = -1; channel->bad_payload = 0; channel->cur_frame = 0; |
38f993ad8 V4L/DVB (8125): T... |
2500 |
for (j = 0; j < SYS_FRAMES; j++) { |
fe85ce90a V4L/DVB: s2255drv... |
2501 2502 |
channel->buffer.frame[j].ulState = 0; channel->buffer.frame[j].cur_size = 0; |
38f993ad8 V4L/DVB (8125): T... |
2503 2504 2505 |
} /* send the start command */ |
3fa006052 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 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 V4L/DVB: s2255drv... |
2513 2514 |
dprintk(2, "start acquire exit[%d] %d ", channel->idx, res); |
38f993ad8 V4L/DVB (8125): T... |
2515 2516 2517 |
kfree(buffer); return 0; } |
fe85ce90a V4L/DVB: s2255drv... |
2518 |
static int s2255_stop_acquire(struct s2255_channel *channel) |
38f993ad8 V4L/DVB (8125): T... |
2519 2520 2521 2522 |
{ unsigned char *buffer; int res; unsigned long chn_rev; |
fe85ce90a V4L/DVB: s2255drv... |
2523 2524 |
struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev); chn_rev = G_chnmap[channel->idx]; |
38f993ad8 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 V4L/DVB (8125): T... |
2531 |
/* send the stop command */ |
3fa006052 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 V4L/DVB (8125): T... |
2535 |
res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); |
38f993ad8 V4L/DVB (8125): T... |
2536 2537 2538 |
if (res != 0) dev_err(&dev->udev->dev, "CMD_STOP error "); |
38f993ad8 V4L/DVB (8125): T... |
2539 |
kfree(buffer); |
fe85ce90a V4L/DVB: s2255drv... |
2540 2541 2542 |
channel->b_acquire = 0; dprintk(4, "%s: chn %d, res %d ", __func__, channel->idx, res); |
14d962602 V4L/DVB (8752): s... |
2543 |
return res; |
38f993ad8 V4L/DVB (8125): T... |
2544 2545 2546 2547 |
} static void s2255_stop_readpipe(struct s2255_dev *dev) { |
ab85c6a33 V4L/DVB: s2255drv... |
2548 |
struct s2255_pipeinfo *pipe = &dev->pipe; |
8b661b508 V4L/DVB: s2255drv... |
2549 |
|
ab85c6a33 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 V4L/DVB (8125): T... |
2556 |
} |
ab85c6a33 V4L/DVB: s2255drv... |
2557 |
dprintk(4, "%s", __func__); |
38f993ad8 V4L/DVB (8125): T... |
2558 2559 |
return; } |
14d962602 V4L/DVB (8752): s... |
2560 |
static void s2255_fwload_start(struct s2255_dev *dev, int reset) |
38f993ad8 V4L/DVB (8125): T... |
2561 |
{ |
14d962602 V4L/DVB (8752): s... |
2562 2563 |
if (reset) s2255_reset_dsppower(dev); |
38f993ad8 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 V4L/DVB (8752): s... |
2586 2587 |
__le32 *pdata; int fw_size; |
85b85482c V4L/DVB: s2255drv... |
2588 2589 |
dprintk(2, "%s ", __func__); |
38f993ad8 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 V4L/DVB (10298): ... |
2593 2594 |
s2255_dev_err(&interface->dev, "out of memory "); |
ff7e22dfa V4L/DVB: s2255drv... |
2595 |
return -ENOMEM; |
38f993ad8 V4L/DVB (8125): T... |
2596 |
} |
fe85ce90a V4L/DVB: s2255drv... |
2597 |
atomic_set(&dev->num_channels, 0); |
5a34d9dfa V4L/DVB: s2255drv... |
2598 |
dev->pid = id->idProduct; |
38f993ad8 V4L/DVB (8125): T... |
2599 2600 |
dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL); if (!dev->fw_data) |
ff7e22dfa V4L/DVB: s2255drv... |
2601 |
goto errorFWDATA1; |
38f993ad8 V4L/DVB (8125): T... |
2602 2603 |
mutex_init(&dev->lock); mutex_init(&dev->open_lock); |
38f993ad8 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 V4L/DVB: s2255drv... |
2610 |
goto errorUDEV; |
38f993ad8 V4L/DVB (8125): T... |
2611 |
} |
d62e85a09 V4L/DVB: s2255drv... |
2612 2613 |
dprintk(1, "dev: %p, udev %p interface %p ", dev, |
38f993ad8 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 V4L/DVB (10298): ... |
2629 2630 |
dev_err(&interface->dev, "Could not find bulk-in endpoint "); |
ff7e22dfa V4L/DVB: s2255drv... |
2631 |
goto errorEP; |
38f993ad8 V4L/DVB (8125): T... |
2632 |
} |
38f993ad8 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 V4L/DVB (8125): T... |
2636 |
init_waitqueue_head(&dev->fw_data->wait_fw); |
4de39f5d6 V4L/DVB: s2255drv... |
2637 |
for (i = 0; i < MAX_CHANNELS; i++) { |
fe85ce90a 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 V4L/DVB: s2255drv... |
2642 |
} |
38f993ad8 V4L/DVB (8125): T... |
2643 2644 |
dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); |
38f993ad8 V4L/DVB (8125): T... |
2645 2646 2647 |
if (!dev->fw_data->fw_urb) { dev_err(&interface->dev, "out of memory! "); |
ff7e22dfa V4L/DVB: s2255drv... |
2648 |
goto errorFWURB; |
38f993ad8 V4L/DVB (8125): T... |
2649 |
} |
ff7e22dfa V4L/DVB: s2255drv... |
2650 |
|
38f993ad8 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 V4L/DVB: s2255drv... |
2655 |
goto errorFWDATA2; |
38f993ad8 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 V4L/DVB: s2255drv... |
2662 |
goto errorREQFW; |
38f993ad8 V4L/DVB (8125): T... |
2663 |
} |
14d962602 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 V4L/DVB (8125): T... |
2667 |
|
14d962602 V4L/DVB (8752): s... |
2668 2669 2670 2671 |
if (*pdata != S2255_FW_MARKER) { printk(KERN_INFO "Firmware invalid. "); retval = -ENODEV; |
ff7e22dfa V4L/DVB: s2255drv... |
2672 |
goto errorFWMARKER; |
14d962602 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 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 V4L/DVB: s2255drv... |
2683 |
if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER) |
ff7e22dfa V4L/DVB: s2255drv... |
2684 |
printk(KERN_WARNING "s2255: 2257 requires firmware %d" |
fe85ce90a V4L/DVB: s2255drv... |
2685 2686 |
" or above. ", S2255_MIN_DSP_COLORFILTER); |
14d962602 V4L/DVB (8752): s... |
2687 |
} |
14d962602 V4L/DVB (8752): s... |
2688 |
usb_reset_device(dev->udev); |
38f993ad8 V4L/DVB (8125): T... |
2689 |
/* load 2255 board specific */ |
abce21f40 V4L/DVB (11605): ... |
2690 2691 |
retval = s2255_board_init(dev); if (retval) |
ff7e22dfa V4L/DVB: s2255drv... |
2692 |
goto errorBOARDINIT; |
38f993ad8 V4L/DVB (8125): T... |
2693 |
spin_lock_init(&dev->slock); |
14d962602 V4L/DVB (8752): s... |
2694 |
s2255_fwload_start(dev, 0); |
ff7e22dfa V4L/DVB: s2255drv... |
2695 2696 2697 |
/* loads v4l specific */ retval = s2255_probe_v4l(dev); if (retval) |
3a67b5cc6 V4L/DVB: s2255drv... |
2698 |
goto errorBOARDINIT; |
38f993ad8 V4L/DVB (8125): T... |
2699 2700 2701 |
dev_info(&interface->dev, "Sensoray 2255 detected "); return 0; |
ff7e22dfa 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 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 V4L/DVB: s2255drv... |
2728 |
struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface)); |
14d962602 V4L/DVB (8752): s... |
2729 |
int i; |
fe85ce90a V4L/DVB: s2255drv... |
2730 |
int channels = atomic_read(&dev->num_channels); |
a19a5cd7b [media] s2255drv:... |
2731 |
mutex_lock(&dev->lock); |
fe85ce90a V4L/DVB: s2255drv... |
2732 |
v4l2_device_disconnect(&dev->v4l2_dev); |
a19a5cd7b [media] s2255drv:... |
2733 |
mutex_unlock(&dev->lock); |
d62e85a09 V4L/DVB: s2255drv... |
2734 |
/*see comments in the uvc_driver.c usb disconnect function */ |
fe85ce90a V4L/DVB: s2255drv... |
2735 |
atomic_inc(&dev->num_channels); |
ff7e22dfa V4L/DVB: s2255drv... |
2736 |
/* unregister each video device. */ |
fe85ce90a V4L/DVB: s2255drv... |
2737 2738 |
for (i = 0; i < channels; i++) video_unregister_device(&dev->channel[i].vdev); |
ff7e22dfa V4L/DVB: s2255drv... |
2739 |
/* wake up any of our timers */ |
14d962602 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 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 V4L/DVB (8752): s... |
2747 |
} |
fe85ce90a V4L/DVB: s2255drv... |
2748 |
if (atomic_dec_and_test(&dev->num_channels)) |
d62e85a09 V4L/DVB: s2255drv... |
2749 |
s2255_destroy(dev); |
ff7e22dfa V4L/DVB: s2255drv... |
2750 2751 |
dev_info(&interface->dev, "%s ", __func__); |
38f993ad8 V4L/DVB (8125): T... |
2752 2753 2754 |
} static struct usb_driver s2255_driver = { |
be9ed5117 V4L/DVB (10298): ... |
2755 |
.name = S2255_DRIVER_NAME, |
38f993ad8 V4L/DVB (8125): T... |
2756 2757 2758 2759 |
.probe = s2255_probe, .disconnect = s2255_disconnect, .id_table = s2255_table, }; |
ecb3b2b35 USB: convert driv... |
2760 |
module_usb_driver(s2255_driver); |
38f993ad8 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 [media] Stop usin... |
2765 |
MODULE_VERSION(S2255_VERSION); |