diff options
Diffstat (limited to 'drivers/media/video/s2255drv.c')
-rw-r--r-- | drivers/media/video/s2255drv.c | 1161 |
1 files changed, 632 insertions, 529 deletions
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 3de914deb8ee..3c7a79f3812a 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * s2255drv.c - a driver for the Sensoray 2255 USB video capture device | 2 | * s2255drv.c - a driver for the Sensoray 2255 USB video capture device |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2008 by Sensoray Company Inc. | 4 | * Copyright (C) 2007-2010 by Sensoray Company Inc. |
5 | * Dean Anderson | 5 | * Dean Anderson |
6 | * | 6 | * |
7 | * Some video buffer code based on vivi driver: | 7 | * Some video buffer code based on vivi driver: |
@@ -52,14 +52,19 @@ | |||
52 | #include <linux/smp_lock.h> | 52 | #include <linux/smp_lock.h> |
53 | #include <media/videobuf-vmalloc.h> | 53 | #include <media/videobuf-vmalloc.h> |
54 | #include <media/v4l2-common.h> | 54 | #include <media/v4l2-common.h> |
55 | #include <media/v4l2-device.h> | ||
55 | #include <media/v4l2-ioctl.h> | 56 | #include <media/v4l2-ioctl.h> |
56 | #include <linux/vmalloc.h> | 57 | #include <linux/vmalloc.h> |
57 | #include <linux/usb.h> | 58 | #include <linux/usb.h> |
58 | 59 | ||
60 | #define S2255_MAJOR_VERSION 1 | ||
61 | #define S2255_MINOR_VERSION 20 | ||
62 | #define S2255_RELEASE 0 | ||
63 | #define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ | ||
64 | S2255_MINOR_VERSION, \ | ||
65 | S2255_RELEASE) | ||
59 | #define FIRMWARE_FILE_NAME "f2255usb.bin" | 66 | #define FIRMWARE_FILE_NAME "f2255usb.bin" |
60 | 67 | ||
61 | |||
62 | |||
63 | /* default JPEG quality */ | 68 | /* default JPEG quality */ |
64 | #define S2255_DEF_JPEG_QUAL 50 | 69 | #define S2255_DEF_JPEG_QUAL 50 |
65 | /* vendor request in */ | 70 | /* vendor request in */ |
@@ -76,14 +81,14 @@ | |||
76 | #define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME) | 81 | #define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME) |
77 | #define S2255_DEF_BUFS 16 | 82 | #define S2255_DEF_BUFS 16 |
78 | #define S2255_SETMODE_TIMEOUT 500 | 83 | #define S2255_SETMODE_TIMEOUT 500 |
79 | #define MAX_CHANNELS 4 | 84 | #define S2255_VIDSTATUS_TIMEOUT 350 |
80 | #define S2255_MARKER_FRAME 0x2255DA4AL | 85 | #define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL) |
81 | #define S2255_MARKER_RESPONSE 0x2255ACACL | 86 | #define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL) |
82 | #define S2255_RESPONSE_SETMODE 0x01 | 87 | #define S2255_RESPONSE_SETMODE cpu_to_le32(0x01) |
83 | #define S2255_RESPONSE_FW 0x10 | 88 | #define S2255_RESPONSE_FW cpu_to_le32(0x10) |
89 | #define S2255_RESPONSE_STATUS cpu_to_le32(0x20) | ||
84 | #define S2255_USB_XFER_SIZE (16 * 1024) | 90 | #define S2255_USB_XFER_SIZE (16 * 1024) |
85 | #define MAX_CHANNELS 4 | 91 | #define MAX_CHANNELS 4 |
86 | #define MAX_PIPE_BUFFERS 1 | ||
87 | #define SYS_FRAMES 4 | 92 | #define SYS_FRAMES 4 |
88 | /* maximum size is PAL full size plus room for the marker header(s) */ | 93 | /* maximum size is PAL full size plus room for the marker header(s) */ |
89 | #define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096) | 94 | #define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096) |
@@ -118,9 +123,10 @@ | |||
118 | #define COLOR_YUVPK 2 /* YUV packed */ | 123 | #define COLOR_YUVPK 2 /* YUV packed */ |
119 | #define COLOR_Y8 4 /* monochrome */ | 124 | #define COLOR_Y8 4 /* monochrome */ |
120 | #define COLOR_JPG 5 /* JPEG */ | 125 | #define COLOR_JPG 5 /* JPEG */ |
121 | #define MASK_COLOR 0xff | ||
122 | #define MASK_JPG_QUALITY 0xff00 | ||
123 | 126 | ||
127 | #define MASK_COLOR 0x000000ff | ||
128 | #define MASK_JPG_QUALITY 0x0000ff00 | ||
129 | #define MASK_INPUT_TYPE 0x000f0000 | ||
124 | /* frame decimation. Not implemented by V4L yet(experimental in V4L) */ | 130 | /* frame decimation. Not implemented by V4L yet(experimental in V4L) */ |
125 | #define FDEC_1 1 /* capture every frame. default */ | 131 | #define FDEC_1 1 /* capture every frame. default */ |
126 | #define FDEC_2 2 /* capture every 2nd frame */ | 132 | #define FDEC_2 2 /* capture every 2nd frame */ |
@@ -139,12 +145,12 @@ | |||
139 | #define DEF_HUE 0 | 145 | #define DEF_HUE 0 |
140 | 146 | ||
141 | /* usb config commands */ | 147 | /* usb config commands */ |
142 | #define IN_DATA_TOKEN 0x2255c0de | 148 | #define IN_DATA_TOKEN cpu_to_le32(0x2255c0de) |
143 | #define CMD_2255 0xc2255000 | 149 | #define CMD_2255 cpu_to_le32(0xc2255000) |
144 | #define CMD_SET_MODE (CMD_2255 | 0x10) | 150 | #define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10)) |
145 | #define CMD_START (CMD_2255 | 0x20) | 151 | #define CMD_START cpu_to_le32((CMD_2255 | 0x20)) |
146 | #define CMD_STOP (CMD_2255 | 0x30) | 152 | #define CMD_STOP cpu_to_le32((CMD_2255 | 0x30)) |
147 | #define CMD_STATUS (CMD_2255 | 0x40) | 153 | #define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40)) |
148 | 154 | ||
149 | struct s2255_mode { | 155 | struct s2255_mode { |
150 | u32 format; /* input video format (NTSC, PAL) */ | 156 | u32 format; /* input video format (NTSC, PAL) */ |
@@ -194,7 +200,6 @@ struct s2255_dmaqueue { | |||
194 | #define S2255_FW_SUCCESS 2 | 200 | #define S2255_FW_SUCCESS 2 |
195 | #define S2255_FW_FAILED 3 | 201 | #define S2255_FW_FAILED 3 |
196 | #define S2255_FW_DISCONNECTING 4 | 202 | #define S2255_FW_DISCONNECTING 4 |
197 | |||
198 | #define S2255_FW_MARKER cpu_to_le32(0x22552f2f) | 203 | #define S2255_FW_MARKER cpu_to_le32(0x22552f2f) |
199 | /* 2255 read states */ | 204 | /* 2255 read states */ |
200 | #define S2255_READ_IDLE 0 | 205 | #define S2255_READ_IDLE 0 |
@@ -223,8 +228,10 @@ struct s2255_pipeinfo { | |||
223 | struct s2255_fmt; /*forward declaration */ | 228 | struct s2255_fmt; /*forward declaration */ |
224 | 229 | ||
225 | struct s2255_dev { | 230 | struct s2255_dev { |
231 | struct video_device vdev[MAX_CHANNELS]; | ||
232 | struct v4l2_device v4l2_dev; | ||
233 | atomic_t channels; /* number of channels registered */ | ||
226 | int frames; | 234 | int frames; |
227 | int users[MAX_CHANNELS]; | ||
228 | struct mutex lock; | 235 | struct mutex lock; |
229 | struct mutex open_lock; | 236 | struct mutex open_lock; |
230 | int resources[MAX_CHANNELS]; | 237 | int resources[MAX_CHANNELS]; |
@@ -233,11 +240,10 @@ struct s2255_dev { | |||
233 | u8 read_endpoint; | 240 | u8 read_endpoint; |
234 | 241 | ||
235 | struct s2255_dmaqueue vidq[MAX_CHANNELS]; | 242 | struct s2255_dmaqueue vidq[MAX_CHANNELS]; |
236 | struct video_device *vdev[MAX_CHANNELS]; | ||
237 | struct timer_list timer; | 243 | struct timer_list timer; |
238 | struct s2255_fw *fw_data; | 244 | struct s2255_fw *fw_data; |
239 | struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; | 245 | struct s2255_pipeinfo pipe; |
240 | struct s2255_bufferi buffer[MAX_CHANNELS]; | 246 | struct s2255_bufferi buffer[MAX_CHANNELS]; |
241 | struct s2255_mode mode[MAX_CHANNELS]; | 247 | struct s2255_mode mode[MAX_CHANNELS]; |
242 | /* jpeg compression */ | 248 | /* jpeg compression */ |
243 | struct v4l2_jpegcompression jc[MAX_CHANNELS]; | 249 | struct v4l2_jpegcompression jc[MAX_CHANNELS]; |
@@ -261,11 +267,21 @@ struct s2255_dev { | |||
261 | int chn_configured[MAX_CHANNELS]; | 267 | int chn_configured[MAX_CHANNELS]; |
262 | wait_queue_head_t wait_setmode[MAX_CHANNELS]; | 268 | wait_queue_head_t wait_setmode[MAX_CHANNELS]; |
263 | int setmode_ready[MAX_CHANNELS]; | 269 | int setmode_ready[MAX_CHANNELS]; |
270 | /* video status items */ | ||
271 | int vidstatus[MAX_CHANNELS]; | ||
272 | wait_queue_head_t wait_vidstatus[MAX_CHANNELS]; | ||
273 | int vidstatus_ready[MAX_CHANNELS]; | ||
264 | int chn_ready; | 274 | int chn_ready; |
265 | struct kref kref; | ||
266 | spinlock_t slock; | 275 | spinlock_t slock; |
276 | /* dsp firmware version (f2255usb.bin) */ | ||
277 | int dsp_fw_ver; | ||
278 | u16 pid; /* product id */ | ||
267 | }; | 279 | }; |
268 | #define to_s2255_dev(d) container_of(d, struct s2255_dev, kref) | 280 | |
281 | static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev) | ||
282 | { | ||
283 | return container_of(v4l2_dev, struct s2255_dev, v4l2_dev); | ||
284 | } | ||
269 | 285 | ||
270 | struct s2255_fmt { | 286 | struct s2255_fmt { |
271 | char *name; | 287 | char *name; |
@@ -296,17 +312,43 @@ struct s2255_fh { | |||
296 | 312 | ||
297 | /* current cypress EEPROM firmware version */ | 313 | /* current cypress EEPROM firmware version */ |
298 | #define S2255_CUR_USB_FWVER ((3 << 8) | 6) | 314 | #define S2255_CUR_USB_FWVER ((3 << 8) | 6) |
299 | #define S2255_MAJOR_VERSION 1 | 315 | /* current DSP FW version */ |
300 | #define S2255_MINOR_VERSION 14 | 316 | #define S2255_CUR_DSP_FWVER 8 |
301 | #define S2255_RELEASE 0 | 317 | /* Need DSP version 5+ for video status feature */ |
302 | #define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ | 318 | #define S2255_MIN_DSP_STATUS 5 |
303 | S2255_MINOR_VERSION, \ | 319 | #define S2255_MIN_DSP_COLORFILTER 8 |
304 | S2255_RELEASE) | ||
305 | |||
306 | /* vendor ids */ | ||
307 | #define USB_S2255_VENDOR_ID 0x1943 | ||
308 | #define USB_S2255_PRODUCT_ID 0x2255 | ||
309 | #define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC) | 320 | #define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC) |
321 | |||
322 | /* private V4L2 controls */ | ||
323 | |||
324 | /* | ||
325 | * The following chart displays how COLORFILTER should be set | ||
326 | * ========================================================= | ||
327 | * = fourcc = COLORFILTER = | ||
328 | * = =============================== | ||
329 | * = = 0 = 1 = | ||
330 | * ========================================================= | ||
331 | * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome= | ||
332 | * = = s-video or = composite = | ||
333 | * = = B/W camera = input = | ||
334 | * ========================================================= | ||
335 | * = other = color, svideo = color, = | ||
336 | * = = = composite = | ||
337 | * ========================================================= | ||
338 | * | ||
339 | * Notes: | ||
340 | * channels 0-3 on 2255 are composite | ||
341 | * channels 0-1 on 2257 are composite, 2-3 are s-video | ||
342 | * If COLORFILTER is 0 with a composite color camera connected, | ||
343 | * the output will appear monochrome but hatching | ||
344 | * will occur. | ||
345 | * COLORFILTER is different from "color killer" and "color effects" | ||
346 | * for reasons above. | ||
347 | */ | ||
348 | #define S2255_V4L2_YC_ON 1 | ||
349 | #define S2255_V4L2_YC_OFF 0 | ||
350 | #define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0) | ||
351 | |||
310 | /* frame prefix size (sent once every frame) */ | 352 | /* frame prefix size (sent once every frame) */ |
311 | #define PREFIX_SIZE 512 | 353 | #define PREFIX_SIZE 512 |
312 | 354 | ||
@@ -325,9 +367,8 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, | |||
325 | static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, | 367 | static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, |
326 | struct s2255_mode *mode); | 368 | struct s2255_mode *mode); |
327 | static int s2255_board_shutdown(struct s2255_dev *dev); | 369 | static int s2255_board_shutdown(struct s2255_dev *dev); |
328 | static void s2255_exit_v4l(struct s2255_dev *dev); | ||
329 | static void s2255_fwload_start(struct s2255_dev *dev, int reset); | 370 | static void s2255_fwload_start(struct s2255_dev *dev, int reset); |
330 | static void s2255_destroy(struct kref *kref); | 371 | static void s2255_destroy(struct s2255_dev *dev); |
331 | static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req, | 372 | static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req, |
332 | u16 index, u16 value, void *buf, | 373 | u16 index, u16 value, void *buf, |
333 | s32 buf_len, int bOut); | 374 | s32 buf_len, int bOut); |
@@ -347,7 +388,6 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req, | |||
347 | 388 | ||
348 | static struct usb_driver s2255_driver; | 389 | static struct usb_driver s2255_driver; |
349 | 390 | ||
350 | |||
351 | /* Declare static vars that will be used as parameters */ | 391 | /* Declare static vars that will be used as parameters */ |
352 | static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ | 392 | static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ |
353 | 393 | ||
@@ -362,58 +402,16 @@ module_param(video_nr, int, 0644); | |||
362 | MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)"); | 402 | MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)"); |
363 | 403 | ||
364 | /* USB device table */ | 404 | /* USB device table */ |
405 | #define USB_SENSORAY_VID 0x1943 | ||
365 | static struct usb_device_id s2255_table[] = { | 406 | static struct usb_device_id s2255_table[] = { |
366 | {USB_DEVICE(USB_S2255_VENDOR_ID, USB_S2255_PRODUCT_ID)}, | 407 | {USB_DEVICE(USB_SENSORAY_VID, 0x2255)}, |
408 | {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/ | ||
367 | { } /* Terminating entry */ | 409 | { } /* Terminating entry */ |
368 | }; | 410 | }; |
369 | MODULE_DEVICE_TABLE(usb, s2255_table); | 411 | MODULE_DEVICE_TABLE(usb, s2255_table); |
370 | 412 | ||
371 | |||
372 | #define BUFFER_TIMEOUT msecs_to_jiffies(400) | 413 | #define BUFFER_TIMEOUT msecs_to_jiffies(400) |
373 | 414 | ||
374 | /* supported controls */ | ||
375 | static struct v4l2_queryctrl s2255_qctrl[] = { | ||
376 | { | ||
377 | .id = V4L2_CID_BRIGHTNESS, | ||
378 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
379 | .name = "Brightness", | ||
380 | .minimum = -127, | ||
381 | .maximum = 128, | ||
382 | .step = 1, | ||
383 | .default_value = 0, | ||
384 | .flags = 0, | ||
385 | }, { | ||
386 | .id = V4L2_CID_CONTRAST, | ||
387 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
388 | .name = "Contrast", | ||
389 | .minimum = 0, | ||
390 | .maximum = 255, | ||
391 | .step = 0x1, | ||
392 | .default_value = DEF_CONTRAST, | ||
393 | .flags = 0, | ||
394 | }, { | ||
395 | .id = V4L2_CID_SATURATION, | ||
396 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
397 | .name = "Saturation", | ||
398 | .minimum = 0, | ||
399 | .maximum = 255, | ||
400 | .step = 0x1, | ||
401 | .default_value = DEF_SATURATION, | ||
402 | .flags = 0, | ||
403 | }, { | ||
404 | .id = V4L2_CID_HUE, | ||
405 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
406 | .name = "Hue", | ||
407 | .minimum = 0, | ||
408 | .maximum = 255, | ||
409 | .step = 0x1, | ||
410 | .default_value = DEF_HUE, | ||
411 | .flags = 0, | ||
412 | } | ||
413 | }; | ||
414 | |||
415 | static int qctl_regs[ARRAY_SIZE(s2255_qctrl)]; | ||
416 | |||
417 | /* image formats. */ | 415 | /* image formats. */ |
418 | static const struct s2255_fmt formats[] = { | 416 | static const struct s2255_fmt formats[] = { |
419 | { | 417 | { |
@@ -505,7 +503,7 @@ static void s2255_reset_dsppower(struct s2255_dev *dev) | |||
505 | static void s2255_timer(unsigned long user_data) | 503 | static void s2255_timer(unsigned long user_data) |
506 | { | 504 | { |
507 | struct s2255_fw *data = (struct s2255_fw *)user_data; | 505 | struct s2255_fw *data = (struct s2255_fw *)user_data; |
508 | dprintk(100, "s2255 timer\n"); | 506 | dprintk(100, "%s\n", __func__); |
509 | if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) { | 507 | if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) { |
510 | printk(KERN_ERR "s2255: can't submit urb\n"); | 508 | printk(KERN_ERR "s2255: can't submit urb\n"); |
511 | atomic_set(&data->fw_state, S2255_FW_FAILED); | 509 | atomic_set(&data->fw_state, S2255_FW_FAILED); |
@@ -527,7 +525,7 @@ static void s2255_fwchunk_complete(struct urb *urb) | |||
527 | struct s2255_fw *data = urb->context; | 525 | struct s2255_fw *data = urb->context; |
528 | struct usb_device *udev = urb->dev; | 526 | struct usb_device *udev = urb->dev; |
529 | int len; | 527 | int len; |
530 | dprintk(100, "udev %p urb %p", udev, urb); | 528 | dprintk(100, "%s: udev %p urb %p", __func__, udev, urb); |
531 | if (urb->status) { | 529 | if (urb->status) { |
532 | dev_err(&udev->dev, "URB failed with status %d\n", urb->status); | 530 | dev_err(&udev->dev, "URB failed with status %d\n", urb->status); |
533 | atomic_set(&data->fw_state, S2255_FW_FAILED); | 531 | atomic_set(&data->fw_state, S2255_FW_FAILED); |
@@ -573,8 +571,8 @@ static void s2255_fwchunk_complete(struct urb *urb) | |||
573 | data->fw_loaded += len; | 571 | data->fw_loaded += len; |
574 | } else { | 572 | } else { |
575 | atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT); | 573 | atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT); |
574 | dprintk(100, "%s: firmware upload complete\n", __func__); | ||
576 | } | 575 | } |
577 | dprintk(100, "2255 complete done\n"); | ||
578 | return; | 576 | return; |
579 | 577 | ||
580 | } | 578 | } |
@@ -585,9 +583,7 @@ static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize) | |||
585 | struct s2255_buffer *buf; | 583 | struct s2255_buffer *buf; |
586 | unsigned long flags = 0; | 584 | unsigned long flags = 0; |
587 | int rc = 0; | 585 | int rc = 0; |
588 | dprintk(2, "wakeup: %p channel: %d\n", &dma_q, chn); | ||
589 | spin_lock_irqsave(&dev->slock, flags); | 586 | spin_lock_irqsave(&dev->slock, flags); |
590 | |||
591 | if (list_empty(&dma_q->active)) { | 587 | if (list_empty(&dma_q->active)) { |
592 | dprintk(1, "No active queue to serve\n"); | 588 | dprintk(1, "No active queue to serve\n"); |
593 | rc = -1; | 589 | rc = -1; |
@@ -595,23 +591,19 @@ static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize) | |||
595 | } | 591 | } |
596 | buf = list_entry(dma_q->active.next, | 592 | buf = list_entry(dma_q->active.next, |
597 | struct s2255_buffer, vb.queue); | 593 | struct s2255_buffer, vb.queue); |
598 | |||
599 | list_del(&buf->vb.queue); | 594 | list_del(&buf->vb.queue); |
600 | do_gettimeofday(&buf->vb.ts); | 595 | do_gettimeofday(&buf->vb.ts); |
601 | dprintk(100, "[%p/%d] wakeup\n", buf, buf->vb.i); | ||
602 | s2255_fillbuff(dev, buf, dma_q->channel, jpgsize); | 596 | s2255_fillbuff(dev, buf, dma_q->channel, jpgsize); |
603 | wake_up(&buf->vb.done); | 597 | wake_up(&buf->vb.done); |
604 | dprintk(2, "wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i); | 598 | dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i); |
605 | unlock: | 599 | unlock: |
606 | spin_unlock_irqrestore(&dev->slock, flags); | 600 | spin_unlock_irqrestore(&dev->slock, flags); |
607 | return 0; | 601 | return 0; |
608 | } | 602 | } |
609 | 603 | ||
610 | |||
611 | static const struct s2255_fmt *format_by_fourcc(int fourcc) | 604 | static const struct s2255_fmt *format_by_fourcc(int fourcc) |
612 | { | 605 | { |
613 | unsigned int i; | 606 | unsigned int i; |
614 | |||
615 | for (i = 0; i < ARRAY_SIZE(formats); i++) { | 607 | for (i = 0; i < ARRAY_SIZE(formats); i++) { |
616 | if (-1 == formats[i].fourcc) | 608 | if (-1 == formats[i].fourcc) |
617 | continue; | 609 | continue; |
@@ -621,9 +613,6 @@ static const struct s2255_fmt *format_by_fourcc(int fourcc) | |||
621 | return NULL; | 613 | return NULL; |
622 | } | 614 | } |
623 | 615 | ||
624 | |||
625 | |||
626 | |||
627 | /* video buffer vmalloc implementation based partly on VIVI driver which is | 616 | /* video buffer vmalloc implementation based partly on VIVI driver which is |
628 | * Copyright (c) 2006 by | 617 | * Copyright (c) 2006 by |
629 | * Mauro Carvalho Chehab <mchehab--a.t--infradead.org> | 618 | * Mauro Carvalho Chehab <mchehab--a.t--infradead.org> |
@@ -703,8 +692,8 @@ static int buffer_setup(struct videobuf_queue *vq, unsigned int *count, | |||
703 | if (0 == *count) | 692 | if (0 == *count) |
704 | *count = S2255_DEF_BUFS; | 693 | *count = S2255_DEF_BUFS; |
705 | 694 | ||
706 | while (*size * (*count) > vid_limit * 1024 * 1024) | 695 | if (*size * *count > vid_limit * 1024 * 1024) |
707 | (*count)--; | 696 | *count = (vid_limit * 1024 * 1024) / *size; |
708 | 697 | ||
709 | return 0; | 698 | return 0; |
710 | } | 699 | } |
@@ -727,10 +716,10 @@ static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
727 | if (fh->fmt == NULL) | 716 | if (fh->fmt == NULL) |
728 | return -EINVAL; | 717 | return -EINVAL; |
729 | 718 | ||
730 | if ((fh->width < norm_minw(fh->dev->vdev[fh->channel])) || | 719 | if ((fh->width < norm_minw(&fh->dev->vdev[fh->channel])) || |
731 | (fh->width > norm_maxw(fh->dev->vdev[fh->channel])) || | 720 | (fh->width > norm_maxw(&fh->dev->vdev[fh->channel])) || |
732 | (fh->height < norm_minh(fh->dev->vdev[fh->channel])) || | 721 | (fh->height < norm_minh(&fh->dev->vdev[fh->channel])) || |
733 | (fh->height > norm_maxh(fh->dev->vdev[fh->channel]))) { | 722 | (fh->height > norm_maxh(&fh->dev->vdev[fh->channel]))) { |
734 | dprintk(4, "invalid buffer prepare\n"); | 723 | dprintk(4, "invalid buffer prepare\n"); |
735 | return -EINVAL; | 724 | return -EINVAL; |
736 | } | 725 | } |
@@ -747,7 +736,6 @@ static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
747 | buf->vb.height = fh->height; | 736 | buf->vb.height = fh->height; |
748 | buf->vb.field = field; | 737 | buf->vb.field = field; |
749 | 738 | ||
750 | |||
751 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 739 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { |
752 | rc = videobuf_iolock(vq, &buf->vb, NULL); | 740 | rc = videobuf_iolock(vq, &buf->vb, NULL); |
753 | if (rc < 0) | 741 | if (rc < 0) |
@@ -767,9 +755,7 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | |||
767 | struct s2255_fh *fh = vq->priv_data; | 755 | struct s2255_fh *fh = vq->priv_data; |
768 | struct s2255_dev *dev = fh->dev; | 756 | struct s2255_dev *dev = fh->dev; |
769 | struct s2255_dmaqueue *vidq = &dev->vidq[fh->channel]; | 757 | struct s2255_dmaqueue *vidq = &dev->vidq[fh->channel]; |
770 | |||
771 | dprintk(1, "%s\n", __func__); | 758 | dprintk(1, "%s\n", __func__); |
772 | |||
773 | buf->vb.state = VIDEOBUF_QUEUED; | 759 | buf->vb.state = VIDEOBUF_QUEUED; |
774 | list_add_tail(&buf->vb.queue, &vidq->active); | 760 | list_add_tail(&buf->vb.queue, &vidq->active); |
775 | } | 761 | } |
@@ -828,6 +814,27 @@ static void res_free(struct s2255_dev *dev, struct s2255_fh *fh) | |||
828 | dprintk(1, "res: put\n"); | 814 | dprintk(1, "res: put\n"); |
829 | } | 815 | } |
830 | 816 | ||
817 | static int vidioc_querymenu(struct file *file, void *priv, | ||
818 | struct v4l2_querymenu *qmenu) | ||
819 | { | ||
820 | static const char *colorfilter[] = { | ||
821 | "Off", | ||
822 | "On", | ||
823 | NULL | ||
824 | }; | ||
825 | if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) { | ||
826 | int i; | ||
827 | const char **menu_items = colorfilter; | ||
828 | for (i = 0; i < qmenu->index && menu_items[i]; i++) | ||
829 | ; /* do nothing (from v4l2-common.c) */ | ||
830 | if (menu_items[i] == NULL || menu_items[i][0] == '\0') | ||
831 | return -EINVAL; | ||
832 | strlcpy(qmenu->name, menu_items[qmenu->index], | ||
833 | sizeof(qmenu->name)); | ||
834 | return 0; | ||
835 | } | ||
836 | return v4l2_ctrl_query_menu(qmenu, NULL, NULL); | ||
837 | } | ||
831 | 838 | ||
832 | static int vidioc_querycap(struct file *file, void *priv, | 839 | static int vidioc_querycap(struct file *file, void *priv, |
833 | struct v4l2_capability *cap) | 840 | struct v4l2_capability *cap) |
@@ -883,7 +890,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
883 | int is_ntsc; | 890 | int is_ntsc; |
884 | 891 | ||
885 | is_ntsc = | 892 | is_ntsc = |
886 | (dev->vdev[fh->channel]->current_norm & V4L2_STD_NTSC) ? 1 : 0; | 893 | (dev->vdev[fh->channel].current_norm & V4L2_STD_NTSC) ? 1 : 0; |
887 | 894 | ||
888 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 895 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
889 | 896 | ||
@@ -894,10 +901,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
894 | if (field == V4L2_FIELD_ANY) | 901 | if (field == V4L2_FIELD_ANY) |
895 | b_any_field = 1; | 902 | b_any_field = 1; |
896 | 903 | ||
897 | dprintk(4, "try format %d \n", is_ntsc); | 904 | dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n", |
898 | /* supports 3 sizes. see s2255drv.h */ | 905 | __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height); |
899 | dprintk(50, "width test %d, height %d\n", | ||
900 | f->fmt.pix.width, f->fmt.pix.height); | ||
901 | if (is_ntsc) { | 906 | if (is_ntsc) { |
902 | /* NTSC */ | 907 | /* NTSC */ |
903 | if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) { | 908 | if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) { |
@@ -952,29 +957,24 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
952 | } | 957 | } |
953 | } | 958 | } |
954 | if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) { | 959 | if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) { |
955 | dprintk(50, "pal 704\n"); | ||
956 | f->fmt.pix.width = LINE_SZ_4CIFS_PAL; | 960 | f->fmt.pix.width = LINE_SZ_4CIFS_PAL; |
957 | field = V4L2_FIELD_SEQ_TB; | 961 | field = V4L2_FIELD_SEQ_TB; |
958 | } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) { | 962 | } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) { |
959 | dprintk(50, "pal 352A\n"); | ||
960 | f->fmt.pix.width = LINE_SZ_2CIFS_PAL; | 963 | f->fmt.pix.width = LINE_SZ_2CIFS_PAL; |
961 | field = V4L2_FIELD_TOP; | 964 | field = V4L2_FIELD_TOP; |
962 | } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) { | 965 | } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) { |
963 | dprintk(50, "pal 352B\n"); | ||
964 | f->fmt.pix.width = LINE_SZ_1CIFS_PAL; | 966 | f->fmt.pix.width = LINE_SZ_1CIFS_PAL; |
965 | field = V4L2_FIELD_TOP; | 967 | field = V4L2_FIELD_TOP; |
966 | } else { | 968 | } else { |
967 | dprintk(50, "pal 352C\n"); | ||
968 | f->fmt.pix.width = LINE_SZ_1CIFS_PAL; | 969 | f->fmt.pix.width = LINE_SZ_1CIFS_PAL; |
969 | field = V4L2_FIELD_TOP; | 970 | field = V4L2_FIELD_TOP; |
970 | } | 971 | } |
971 | } | 972 | } |
972 | |||
973 | dprintk(50, "width %d height %d field %d \n", f->fmt.pix.width, | ||
974 | f->fmt.pix.height, f->fmt.pix.field); | ||
975 | f->fmt.pix.field = field; | 973 | f->fmt.pix.field = field; |
976 | f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; | 974 | f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; |
977 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | 975 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; |
976 | dprintk(50, "%s: set width %d height %d field %d\n", __func__, | ||
977 | f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); | ||
978 | return 0; | 978 | return 0; |
979 | } | 979 | } |
980 | 980 | ||
@@ -1006,7 +1006,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | if (res_locked(fh->dev, fh)) { | 1008 | if (res_locked(fh->dev, fh)) { |
1009 | dprintk(1, "can't change format after started\n"); | 1009 | dprintk(1, "%s: channel busy\n", __func__); |
1010 | ret = -EBUSY; | 1010 | ret = -EBUSY; |
1011 | goto out_s_fmt; | 1011 | goto out_s_fmt; |
1012 | } | 1012 | } |
@@ -1016,17 +1016,14 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
1016 | fh->height = f->fmt.pix.height; | 1016 | fh->height = f->fmt.pix.height; |
1017 | fh->vb_vidq.field = f->fmt.pix.field; | 1017 | fh->vb_vidq.field = f->fmt.pix.field; |
1018 | fh->type = f->type; | 1018 | fh->type = f->type; |
1019 | norm = norm_minw(fh->dev->vdev[fh->channel]); | 1019 | norm = norm_minw(&fh->dev->vdev[fh->channel]); |
1020 | if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) { | 1020 | if (fh->width > norm_minw(&fh->dev->vdev[fh->channel])) { |
1021 | if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) { | 1021 | if (fh->height > norm_minh(&fh->dev->vdev[fh->channel])) { |
1022 | if (fh->dev->cap_parm[fh->channel].capturemode & | 1022 | if (fh->dev->cap_parm[fh->channel].capturemode & |
1023 | V4L2_MODE_HIGHQUALITY) { | 1023 | V4L2_MODE_HIGHQUALITY) |
1024 | fh->mode.scale = SCALE_4CIFSI; | 1024 | fh->mode.scale = SCALE_4CIFSI; |
1025 | dprintk(2, "scale 4CIFSI\n"); | 1025 | else |
1026 | } else { | ||
1027 | fh->mode.scale = SCALE_4CIFS; | 1026 | fh->mode.scale = SCALE_4CIFS; |
1028 | dprintk(2, "scale 4CIFS\n"); | ||
1029 | } | ||
1030 | } else | 1027 | } else |
1031 | fh->mode.scale = SCALE_2CIFS; | 1028 | fh->mode.scale = SCALE_2CIFS; |
1032 | 1029 | ||
@@ -1037,19 +1034,23 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
1037 | /* color mode */ | 1034 | /* color mode */ |
1038 | switch (fh->fmt->fourcc) { | 1035 | switch (fh->fmt->fourcc) { |
1039 | case V4L2_PIX_FMT_GREY: | 1036 | case V4L2_PIX_FMT_GREY: |
1040 | fh->mode.color = COLOR_Y8; | 1037 | fh->mode.color &= ~MASK_COLOR; |
1038 | fh->mode.color |= COLOR_Y8; | ||
1041 | break; | 1039 | break; |
1042 | case V4L2_PIX_FMT_JPEG: | 1040 | case V4L2_PIX_FMT_JPEG: |
1043 | fh->mode.color = COLOR_JPG | | 1041 | fh->mode.color &= ~MASK_COLOR; |
1044 | (fh->dev->jc[fh->channel].quality << 8); | 1042 | fh->mode.color |= COLOR_JPG; |
1043 | fh->mode.color |= (fh->dev->jc[fh->channel].quality << 8); | ||
1045 | break; | 1044 | break; |
1046 | case V4L2_PIX_FMT_YUV422P: | 1045 | case V4L2_PIX_FMT_YUV422P: |
1047 | fh->mode.color = COLOR_YUVPL; | 1046 | fh->mode.color &= ~MASK_COLOR; |
1047 | fh->mode.color |= COLOR_YUVPL; | ||
1048 | break; | 1048 | break; |
1049 | case V4L2_PIX_FMT_YUYV: | 1049 | case V4L2_PIX_FMT_YUYV: |
1050 | case V4L2_PIX_FMT_UYVY: | 1050 | case V4L2_PIX_FMT_UYVY: |
1051 | default: | 1051 | default: |
1052 | fh->mode.color = COLOR_YUVPK; | 1052 | fh->mode.color &= ~MASK_COLOR; |
1053 | fh->mode.color |= COLOR_YUVPK; | ||
1053 | break; | 1054 | break; |
1054 | } | 1055 | } |
1055 | ret = 0; | 1056 | ret = 0; |
@@ -1178,19 +1179,13 @@ static u32 get_transfer_size(struct s2255_mode *mode) | |||
1178 | return usbInSize; | 1179 | return usbInSize; |
1179 | } | 1180 | } |
1180 | 1181 | ||
1181 | static void dump_verify_mode(struct s2255_dev *sdev, struct s2255_mode *mode) | 1182 | static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode) |
1182 | { | 1183 | { |
1183 | struct device *dev = &sdev->udev->dev; | 1184 | struct device *dev = &sdev->udev->dev; |
1184 | dev_info(dev, "------------------------------------------------\n"); | 1185 | dev_info(dev, "------------------------------------------------\n"); |
1185 | dev_info(dev, "verify mode\n"); | 1186 | dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale); |
1186 | dev_info(dev, "format: %d\n", mode->format); | 1187 | dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color); |
1187 | dev_info(dev, "scale: %d\n", mode->scale); | ||
1188 | dev_info(dev, "fdec: %d\n", mode->fdec); | ||
1189 | dev_info(dev, "color: %d\n", mode->color); | ||
1190 | dev_info(dev, "bright: 0x%x\n", mode->bright); | 1188 | dev_info(dev, "bright: 0x%x\n", mode->bright); |
1191 | dev_info(dev, "restart: 0x%x\n", mode->restart); | ||
1192 | dev_info(dev, "usb_block: 0x%x\n", mode->usb_block); | ||
1193 | dev_info(dev, "single: 0x%x\n", mode->single); | ||
1194 | dev_info(dev, "------------------------------------------------\n"); | 1189 | dev_info(dev, "------------------------------------------------\n"); |
1195 | } | 1190 | } |
1196 | 1191 | ||
@@ -1206,44 +1201,38 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, | |||
1206 | struct s2255_mode *mode) | 1201 | struct s2255_mode *mode) |
1207 | { | 1202 | { |
1208 | int res; | 1203 | int res; |
1209 | u32 *buffer; | 1204 | __le32 *buffer; |
1210 | unsigned long chn_rev; | 1205 | unsigned long chn_rev; |
1211 | |||
1212 | mutex_lock(&dev->lock); | 1206 | mutex_lock(&dev->lock); |
1213 | chn_rev = G_chnmap[chn]; | 1207 | chn_rev = G_chnmap[chn]; |
1214 | dprintk(3, "mode scale [%ld] %p %d\n", chn, mode, mode->scale); | 1208 | dprintk(3, "%s channel %lu\n", __func__, chn); |
1215 | dprintk(3, "mode scale [%ld] %p %d\n", chn, &dev->mode[chn], | ||
1216 | dev->mode[chn].scale); | ||
1217 | dprintk(2, "mode contrast %x\n", mode->contrast); | ||
1218 | |||
1219 | /* if JPEG, set the quality */ | 1209 | /* if JPEG, set the quality */ |
1220 | if ((mode->color & MASK_COLOR) == COLOR_JPG) | 1210 | if ((mode->color & MASK_COLOR) == COLOR_JPG) { |
1221 | mode->color = (dev->jc[chn].quality << 8) | COLOR_JPG; | 1211 | mode->color &= ~MASK_COLOR; |
1222 | 1212 | mode->color |= COLOR_JPG; | |
1213 | mode->color &= ~MASK_JPG_QUALITY; | ||
1214 | mode->color |= (dev->jc[chn].quality << 8); | ||
1215 | } | ||
1223 | /* save the mode */ | 1216 | /* save the mode */ |
1224 | dev->mode[chn] = *mode; | 1217 | dev->mode[chn] = *mode; |
1225 | dev->req_image_size[chn] = get_transfer_size(mode); | 1218 | dev->req_image_size[chn] = get_transfer_size(mode); |
1226 | dprintk(1, "transfer size %ld\n", dev->req_image_size[chn]); | 1219 | dprintk(1, "%s: reqsize %ld\n", __func__, dev->req_image_size[chn]); |
1227 | |||
1228 | buffer = kzalloc(512, GFP_KERNEL); | 1220 | buffer = kzalloc(512, GFP_KERNEL); |
1229 | if (buffer == NULL) { | 1221 | if (buffer == NULL) { |
1230 | dev_err(&dev->udev->dev, "out of mem\n"); | 1222 | dev_err(&dev->udev->dev, "out of mem\n"); |
1231 | mutex_unlock(&dev->lock); | 1223 | mutex_unlock(&dev->lock); |
1232 | return -ENOMEM; | 1224 | return -ENOMEM; |
1233 | } | 1225 | } |
1234 | |||
1235 | /* set the mode */ | 1226 | /* set the mode */ |
1236 | buffer[0] = IN_DATA_TOKEN; | 1227 | buffer[0] = IN_DATA_TOKEN; |
1237 | buffer[1] = (u32) chn_rev; | 1228 | buffer[1] = (__le32) cpu_to_le32(chn_rev); |
1238 | buffer[2] = CMD_SET_MODE; | 1229 | buffer[2] = CMD_SET_MODE; |
1239 | memcpy(&buffer[3], &dev->mode[chn], sizeof(struct s2255_mode)); | 1230 | memcpy(&buffer[3], &dev->mode[chn], sizeof(struct s2255_mode)); |
1240 | dev->setmode_ready[chn] = 0; | 1231 | dev->setmode_ready[chn] = 0; |
1241 | res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); | 1232 | res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); |
1242 | if (debug) | 1233 | if (debug) |
1243 | dump_verify_mode(dev, mode); | 1234 | s2255_print_cfg(dev, mode); |
1244 | kfree(buffer); | 1235 | kfree(buffer); |
1245 | dprintk(1, "set mode done chn %lu, %d\n", chn, res); | ||
1246 | |||
1247 | /* wait at least 3 frames before continuing */ | 1236 | /* wait at least 3 frames before continuing */ |
1248 | if (mode->restart) { | 1237 | if (mode->restart) { |
1249 | wait_event_timeout(dev->wait_setmode[chn], | 1238 | wait_event_timeout(dev->wait_setmode[chn], |
@@ -1254,10 +1243,46 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, | |||
1254 | res = -EFAULT; | 1243 | res = -EFAULT; |
1255 | } | 1244 | } |
1256 | } | 1245 | } |
1257 | |||
1258 | /* clear the restart flag */ | 1246 | /* clear the restart flag */ |
1259 | dev->mode[chn].restart = 0; | 1247 | dev->mode[chn].restart = 0; |
1260 | mutex_unlock(&dev->lock); | 1248 | mutex_unlock(&dev->lock); |
1249 | dprintk(1, "%s chn %lu, result: %d\n", __func__, chn, res); | ||
1250 | return res; | ||
1251 | } | ||
1252 | |||
1253 | static int s2255_cmd_status(struct s2255_dev *dev, unsigned long chn, | ||
1254 | u32 *pstatus) | ||
1255 | { | ||
1256 | int res; | ||
1257 | __le32 *buffer; | ||
1258 | u32 chn_rev; | ||
1259 | mutex_lock(&dev->lock); | ||
1260 | chn_rev = G_chnmap[chn]; | ||
1261 | dprintk(4, "%s chan %lu\n", __func__, chn); | ||
1262 | buffer = kzalloc(512, GFP_KERNEL); | ||
1263 | if (buffer == NULL) { | ||
1264 | dev_err(&dev->udev->dev, "out of mem\n"); | ||
1265 | mutex_unlock(&dev->lock); | ||
1266 | return -ENOMEM; | ||
1267 | } | ||
1268 | /* form the get vid status command */ | ||
1269 | buffer[0] = IN_DATA_TOKEN; | ||
1270 | buffer[1] = (__le32) cpu_to_le32(chn_rev); | ||
1271 | buffer[2] = CMD_STATUS; | ||
1272 | *pstatus = 0; | ||
1273 | dev->vidstatus_ready[chn] = 0; | ||
1274 | res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); | ||
1275 | kfree(buffer); | ||
1276 | wait_event_timeout(dev->wait_vidstatus[chn], | ||
1277 | (dev->vidstatus_ready[chn] != 0), | ||
1278 | msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT)); | ||
1279 | if (dev->vidstatus_ready[chn] != 1) { | ||
1280 | printk(KERN_DEBUG "s2255: no vidstatus response\n"); | ||
1281 | res = -EFAULT; | ||
1282 | } | ||
1283 | *pstatus = dev->vidstatus[chn]; | ||
1284 | dprintk(4, "%s, vid status %d\n", __func__, *pstatus); | ||
1285 | mutex_unlock(&dev->lock); | ||
1261 | return res; | 1286 | return res; |
1262 | } | 1287 | } |
1263 | 1288 | ||
@@ -1291,7 +1316,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | |||
1291 | new_mode = &fh->mode; | 1316 | new_mode = &fh->mode; |
1292 | old_mode = &fh->dev->mode[chn]; | 1317 | old_mode = &fh->dev->mode[chn]; |
1293 | 1318 | ||
1294 | if (new_mode->color != old_mode->color) | 1319 | if ((new_mode->color & MASK_COLOR) != (old_mode->color & MASK_COLOR)) |
1295 | new_mode->restart = 1; | 1320 | new_mode->restart = 1; |
1296 | else if (new_mode->scale != old_mode->scale) | 1321 | else if (new_mode->scale != old_mode->scale) |
1297 | new_mode->restart = 1; | 1322 | new_mode->restart = 1; |
@@ -1302,7 +1327,6 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | |||
1302 | new_mode->restart = 0; | 1327 | new_mode->restart = 0; |
1303 | *old_mode = *new_mode; | 1328 | *old_mode = *new_mode; |
1304 | dev->cur_fmt[chn] = fh->fmt; | 1329 | dev->cur_fmt[chn] = fh->fmt; |
1305 | dprintk(1, "%s[%d]\n", __func__, chn); | ||
1306 | dev->last_frame[chn] = -1; | 1330 | dev->last_frame[chn] = -1; |
1307 | dev->bad_payload[chn] = 0; | 1331 | dev->bad_payload[chn] = 0; |
1308 | dev->cur_frame[chn] = 0; | 1332 | dev->cur_frame[chn] = 0; |
@@ -1325,7 +1349,6 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | |||
1325 | { | 1349 | { |
1326 | struct s2255_fh *fh = priv; | 1350 | struct s2255_fh *fh = priv; |
1327 | struct s2255_dev *dev = fh->dev; | 1351 | struct s2255_dev *dev = fh->dev; |
1328 | |||
1329 | dprintk(4, "%s\n, channel: %d", __func__, fh->channel); | 1352 | dprintk(4, "%s\n, channel: %d", __func__, fh->channel); |
1330 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1353 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
1331 | printk(KERN_ERR "invalid fh type0\n"); | 1354 | printk(KERN_ERR "invalid fh type0\n"); |
@@ -1347,27 +1370,32 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) | |||
1347 | struct s2255_mode *mode; | 1370 | struct s2255_mode *mode; |
1348 | struct videobuf_queue *q = &fh->vb_vidq; | 1371 | struct videobuf_queue *q = &fh->vb_vidq; |
1349 | int ret = 0; | 1372 | int ret = 0; |
1350 | |||
1351 | mutex_lock(&q->vb_lock); | 1373 | mutex_lock(&q->vb_lock); |
1352 | if (videobuf_queue_is_busy(q)) { | 1374 | if (videobuf_queue_is_busy(q)) { |
1353 | dprintk(1, "queue busy\n"); | 1375 | dprintk(1, "queue busy\n"); |
1354 | ret = -EBUSY; | 1376 | ret = -EBUSY; |
1355 | goto out_s_std; | 1377 | goto out_s_std; |
1356 | } | 1378 | } |
1357 | |||
1358 | if (res_locked(fh->dev, fh)) { | 1379 | if (res_locked(fh->dev, fh)) { |
1359 | dprintk(1, "can't change standard after started\n"); | 1380 | dprintk(1, "can't change standard after started\n"); |
1360 | ret = -EBUSY; | 1381 | ret = -EBUSY; |
1361 | goto out_s_std; | 1382 | goto out_s_std; |
1362 | } | 1383 | } |
1363 | mode = &fh->mode; | 1384 | mode = &fh->mode; |
1364 | |||
1365 | if (*i & V4L2_STD_NTSC) { | 1385 | if (*i & V4L2_STD_NTSC) { |
1366 | dprintk(4, "vidioc_s_std NTSC\n"); | 1386 | dprintk(4, "%s NTSC\n", __func__); |
1367 | mode->format = FORMAT_NTSC; | 1387 | /* if changing format, reset frame decimation/intervals */ |
1388 | if (mode->format != FORMAT_NTSC) { | ||
1389 | mode->format = FORMAT_NTSC; | ||
1390 | mode->fdec = FDEC_1; | ||
1391 | } | ||
1368 | } else if (*i & V4L2_STD_PAL) { | 1392 | } else if (*i & V4L2_STD_PAL) { |
1369 | dprintk(4, "vidioc_s_std PAL\n"); | 1393 | dprintk(4, "%s PAL\n", __func__); |
1370 | mode->format = FORMAT_PAL; | 1394 | mode->format = FORMAT_PAL; |
1395 | if (mode->format != FORMAT_PAL) { | ||
1396 | mode->format = FORMAT_PAL; | ||
1397 | mode->fdec = FDEC_1; | ||
1398 | } | ||
1371 | } else { | 1399 | } else { |
1372 | ret = -EINVAL; | 1400 | ret = -EINVAL; |
1373 | } | 1401 | } |
@@ -1386,12 +1414,32 @@ out_s_std: | |||
1386 | static int vidioc_enum_input(struct file *file, void *priv, | 1414 | static int vidioc_enum_input(struct file *file, void *priv, |
1387 | struct v4l2_input *inp) | 1415 | struct v4l2_input *inp) |
1388 | { | 1416 | { |
1417 | struct s2255_fh *fh = priv; | ||
1418 | struct s2255_dev *dev = fh->dev; | ||
1419 | u32 status = 0; | ||
1389 | if (inp->index != 0) | 1420 | if (inp->index != 0) |
1390 | return -EINVAL; | 1421 | return -EINVAL; |
1391 | |||
1392 | inp->type = V4L2_INPUT_TYPE_CAMERA; | 1422 | inp->type = V4L2_INPUT_TYPE_CAMERA; |
1393 | inp->std = S2255_NORMS; | 1423 | inp->std = S2255_NORMS; |
1394 | strlcpy(inp->name, "Camera", sizeof(inp->name)); | 1424 | inp->status = 0; |
1425 | if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) { | ||
1426 | int rc; | ||
1427 | rc = s2255_cmd_status(dev, fh->channel, &status); | ||
1428 | dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status); | ||
1429 | if (rc == 0) | ||
1430 | inp->status = (status & 0x01) ? 0 | ||
1431 | : V4L2_IN_ST_NO_SIGNAL; | ||
1432 | } | ||
1433 | switch (dev->pid) { | ||
1434 | case 0x2255: | ||
1435 | default: | ||
1436 | strlcpy(inp->name, "Composite", sizeof(inp->name)); | ||
1437 | break; | ||
1438 | case 0x2257: | ||
1439 | strlcpy(inp->name, (fh->channel < 2) ? "Composite" : "S-Video", | ||
1440 | sizeof(inp->name)); | ||
1441 | break; | ||
1442 | } | ||
1395 | return 0; | 1443 | return 0; |
1396 | } | 1444 | } |
1397 | 1445 | ||
@@ -1411,74 +1459,113 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | |||
1411 | static int vidioc_queryctrl(struct file *file, void *priv, | 1459 | static int vidioc_queryctrl(struct file *file, void *priv, |
1412 | struct v4l2_queryctrl *qc) | 1460 | struct v4l2_queryctrl *qc) |
1413 | { | 1461 | { |
1414 | int i; | 1462 | struct s2255_fh *fh = priv; |
1415 | 1463 | struct s2255_dev *dev = fh->dev; | |
1416 | for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) | 1464 | switch (qc->id) { |
1417 | if (qc->id && qc->id == s2255_qctrl[i].id) { | 1465 | case V4L2_CID_BRIGHTNESS: |
1418 | memcpy(qc, &(s2255_qctrl[i]), sizeof(*qc)); | 1466 | v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT); |
1419 | return 0; | 1467 | break; |
1420 | } | 1468 | case V4L2_CID_CONTRAST: |
1421 | 1469 | v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST); | |
1422 | dprintk(4, "query_ctrl -EINVAL %d\n", qc->id); | 1470 | break; |
1423 | return -EINVAL; | 1471 | case V4L2_CID_SATURATION: |
1472 | v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION); | ||
1473 | break; | ||
1474 | case V4L2_CID_HUE: | ||
1475 | v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE); | ||
1476 | break; | ||
1477 | case V4L2_CID_PRIVATE_COLORFILTER: | ||
1478 | if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) | ||
1479 | return -EINVAL; | ||
1480 | if ((dev->pid == 0x2257) && (fh->channel > 1)) | ||
1481 | return -EINVAL; | ||
1482 | strlcpy(qc->name, "Color Filter", sizeof(qc->name)); | ||
1483 | qc->type = V4L2_CTRL_TYPE_MENU; | ||
1484 | qc->minimum = 0; | ||
1485 | qc->maximum = 1; | ||
1486 | qc->step = 1; | ||
1487 | qc->default_value = 1; | ||
1488 | qc->flags = 0; | ||
1489 | break; | ||
1490 | default: | ||
1491 | return -EINVAL; | ||
1492 | } | ||
1493 | dprintk(4, "%s, id %d\n", __func__, qc->id); | ||
1494 | return 0; | ||
1424 | } | 1495 | } |
1425 | 1496 | ||
1426 | static int vidioc_g_ctrl(struct file *file, void *priv, | 1497 | static int vidioc_g_ctrl(struct file *file, void *priv, |
1427 | struct v4l2_control *ctrl) | 1498 | struct v4l2_control *ctrl) |
1428 | { | 1499 | { |
1429 | int i; | 1500 | struct s2255_fh *fh = priv; |
1430 | 1501 | struct s2255_dev *dev = fh->dev; | |
1431 | for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) | 1502 | switch (ctrl->id) { |
1432 | if (ctrl->id == s2255_qctrl[i].id) { | 1503 | case V4L2_CID_BRIGHTNESS: |
1433 | ctrl->value = qctl_regs[i]; | 1504 | ctrl->value = fh->mode.bright; |
1434 | return 0; | 1505 | break; |
1435 | } | 1506 | case V4L2_CID_CONTRAST: |
1436 | dprintk(4, "g_ctrl -EINVAL\n"); | 1507 | ctrl->value = fh->mode.contrast; |
1437 | 1508 | break; | |
1438 | return -EINVAL; | 1509 | case V4L2_CID_SATURATION: |
1510 | ctrl->value = fh->mode.saturation; | ||
1511 | break; | ||
1512 | case V4L2_CID_HUE: | ||
1513 | ctrl->value = fh->mode.hue; | ||
1514 | break; | ||
1515 | case V4L2_CID_PRIVATE_COLORFILTER: | ||
1516 | if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) | ||
1517 | return -EINVAL; | ||
1518 | if ((dev->pid == 0x2257) && (fh->channel > 1)) | ||
1519 | return -EINVAL; | ||
1520 | ctrl->value = !((fh->mode.color & MASK_INPUT_TYPE) >> 16); | ||
1521 | break; | ||
1522 | default: | ||
1523 | return -EINVAL; | ||
1524 | } | ||
1525 | dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value); | ||
1526 | return 0; | ||
1439 | } | 1527 | } |
1440 | 1528 | ||
1441 | static int vidioc_s_ctrl(struct file *file, void *priv, | 1529 | static int vidioc_s_ctrl(struct file *file, void *priv, |
1442 | struct v4l2_control *ctrl) | 1530 | struct v4l2_control *ctrl) |
1443 | { | 1531 | { |
1444 | int i; | ||
1445 | struct s2255_fh *fh = priv; | 1532 | struct s2255_fh *fh = priv; |
1446 | struct s2255_dev *dev = fh->dev; | 1533 | struct s2255_dev *dev = fh->dev; |
1447 | struct s2255_mode *mode; | 1534 | struct s2255_mode *mode; |
1448 | mode = &fh->mode; | 1535 | mode = &fh->mode; |
1449 | dprintk(4, "vidioc_s_ctrl\n"); | 1536 | dprintk(4, "%s\n", __func__); |
1450 | for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) { | 1537 | /* update the mode to the corresponding value */ |
1451 | if (ctrl->id == s2255_qctrl[i].id) { | 1538 | switch (ctrl->id) { |
1452 | if (ctrl->value < s2255_qctrl[i].minimum || | 1539 | case V4L2_CID_BRIGHTNESS: |
1453 | ctrl->value > s2255_qctrl[i].maximum) | 1540 | mode->bright = ctrl->value; |
1454 | return -ERANGE; | 1541 | break; |
1455 | 1542 | case V4L2_CID_CONTRAST: | |
1456 | qctl_regs[i] = ctrl->value; | 1543 | mode->contrast = ctrl->value; |
1457 | /* update the mode to the corresponding value */ | 1544 | break; |
1458 | switch (ctrl->id) { | 1545 | case V4L2_CID_HUE: |
1459 | case V4L2_CID_BRIGHTNESS: | 1546 | mode->hue = ctrl->value; |
1460 | mode->bright = ctrl->value; | 1547 | break; |
1461 | break; | 1548 | case V4L2_CID_SATURATION: |
1462 | case V4L2_CID_CONTRAST: | 1549 | mode->saturation = ctrl->value; |
1463 | mode->contrast = ctrl->value; | 1550 | break; |
1464 | break; | 1551 | case V4L2_CID_PRIVATE_COLORFILTER: |
1465 | case V4L2_CID_HUE: | 1552 | if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) |
1466 | mode->hue = ctrl->value; | 1553 | return -EINVAL; |
1467 | break; | 1554 | if ((dev->pid == 0x2257) && (fh->channel > 1)) |
1468 | case V4L2_CID_SATURATION: | 1555 | return -EINVAL; |
1469 | mode->saturation = ctrl->value; | 1556 | mode->color &= ~MASK_INPUT_TYPE; |
1470 | break; | 1557 | mode->color |= ((ctrl->value ? 0 : 1) << 16); |
1471 | } | 1558 | break; |
1472 | mode->restart = 0; | 1559 | default: |
1473 | /* set mode here. Note: stream does not need restarted. | 1560 | return -EINVAL; |
1474 | some V4L programs restart stream unnecessarily | ||
1475 | after a s_crtl. | ||
1476 | */ | ||
1477 | s2255_set_mode(dev, fh->channel, mode); | ||
1478 | return 0; | ||
1479 | } | ||
1480 | } | 1561 | } |
1481 | return -EINVAL; | 1562 | mode->restart = 0; |
1563 | /* set mode here. Note: stream does not need restarted. | ||
1564 | some V4L programs restart stream unnecessarily | ||
1565 | after a s_crtl. | ||
1566 | */ | ||
1567 | s2255_set_mode(dev, fh->channel, mode); | ||
1568 | return 0; | ||
1482 | } | 1569 | } |
1483 | 1570 | ||
1484 | static int vidioc_g_jpegcomp(struct file *file, void *priv, | 1571 | static int vidioc_g_jpegcomp(struct file *file, void *priv, |
@@ -1487,7 +1574,7 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv, | |||
1487 | struct s2255_fh *fh = priv; | 1574 | struct s2255_fh *fh = priv; |
1488 | struct s2255_dev *dev = fh->dev; | 1575 | struct s2255_dev *dev = fh->dev; |
1489 | *jc = dev->jc[fh->channel]; | 1576 | *jc = dev->jc[fh->channel]; |
1490 | dprintk(2, "getting jpegcompression, quality %d\n", jc->quality); | 1577 | dprintk(2, "%s: quality %d\n", __func__, jc->quality); |
1491 | return 0; | 1578 | return 0; |
1492 | } | 1579 | } |
1493 | 1580 | ||
@@ -1499,7 +1586,7 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, | |||
1499 | if (jc->quality < 0 || jc->quality > 100) | 1586 | if (jc->quality < 0 || jc->quality > 100) |
1500 | return -EINVAL; | 1587 | return -EINVAL; |
1501 | dev->jc[fh->channel].quality = jc->quality; | 1588 | dev->jc[fh->channel].quality = jc->quality; |
1502 | dprintk(2, "setting jpeg quality %d\n", jc->quality); | 1589 | dprintk(2, "%s: quality %d\n", __func__, jc->quality); |
1503 | return 0; | 1590 | return 0; |
1504 | } | 1591 | } |
1505 | 1592 | ||
@@ -1508,10 +1595,34 @@ static int vidioc_g_parm(struct file *file, void *priv, | |||
1508 | { | 1595 | { |
1509 | struct s2255_fh *fh = priv; | 1596 | struct s2255_fh *fh = priv; |
1510 | struct s2255_dev *dev = fh->dev; | 1597 | struct s2255_dev *dev = fh->dev; |
1598 | __u32 def_num, def_dem; | ||
1511 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1599 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1512 | return -EINVAL; | 1600 | return -EINVAL; |
1601 | memset(sp, 0, sizeof(struct v4l2_streamparm)); | ||
1602 | sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; | ||
1513 | sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode; | 1603 | sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode; |
1514 | dprintk(2, "getting parm %d\n", sp->parm.capture.capturemode); | 1604 | def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000; |
1605 | def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000; | ||
1606 | sp->parm.capture.timeperframe.denominator = def_dem; | ||
1607 | switch (fh->mode.fdec) { | ||
1608 | default: | ||
1609 | case FDEC_1: | ||
1610 | sp->parm.capture.timeperframe.numerator = def_num; | ||
1611 | break; | ||
1612 | case FDEC_2: | ||
1613 | sp->parm.capture.timeperframe.numerator = def_num * 2; | ||
1614 | break; | ||
1615 | case FDEC_3: | ||
1616 | sp->parm.capture.timeperframe.numerator = def_num * 3; | ||
1617 | break; | ||
1618 | case FDEC_5: | ||
1619 | sp->parm.capture.timeperframe.numerator = def_num * 5; | ||
1620 | break; | ||
1621 | } | ||
1622 | dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__, | ||
1623 | sp->parm.capture.capturemode, | ||
1624 | sp->parm.capture.timeperframe.numerator, | ||
1625 | sp->parm.capture.timeperframe.denominator); | ||
1515 | return 0; | 1626 | return 0; |
1516 | } | 1627 | } |
1517 | 1628 | ||
@@ -1520,15 +1631,79 @@ static int vidioc_s_parm(struct file *file, void *priv, | |||
1520 | { | 1631 | { |
1521 | struct s2255_fh *fh = priv; | 1632 | struct s2255_fh *fh = priv; |
1522 | struct s2255_dev *dev = fh->dev; | 1633 | struct s2255_dev *dev = fh->dev; |
1523 | 1634 | int fdec = FDEC_1; | |
1635 | __u32 def_num, def_dem; | ||
1524 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1636 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1525 | return -EINVAL; | 1637 | return -EINVAL; |
1638 | /* high quality capture mode requires a stream restart */ | ||
1639 | if (dev->cap_parm[fh->channel].capturemode | ||
1640 | != sp->parm.capture.capturemode && res_locked(fh->dev, fh)) | ||
1641 | return -EBUSY; | ||
1642 | def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000; | ||
1643 | def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000; | ||
1644 | if (def_dem != sp->parm.capture.timeperframe.denominator) | ||
1645 | sp->parm.capture.timeperframe.numerator = def_num; | ||
1646 | else if (sp->parm.capture.timeperframe.numerator <= def_num) | ||
1647 | sp->parm.capture.timeperframe.numerator = def_num; | ||
1648 | else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) { | ||
1649 | sp->parm.capture.timeperframe.numerator = def_num * 2; | ||
1650 | fdec = FDEC_2; | ||
1651 | } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) { | ||
1652 | sp->parm.capture.timeperframe.numerator = def_num * 3; | ||
1653 | fdec = FDEC_3; | ||
1654 | } else { | ||
1655 | sp->parm.capture.timeperframe.numerator = def_num * 5; | ||
1656 | fdec = FDEC_5; | ||
1657 | } | ||
1658 | fh->mode.fdec = fdec; | ||
1659 | sp->parm.capture.timeperframe.denominator = def_dem; | ||
1660 | s2255_set_mode(dev, fh->channel, &fh->mode); | ||
1661 | dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n", | ||
1662 | __func__, | ||
1663 | sp->parm.capture.capturemode, | ||
1664 | sp->parm.capture.timeperframe.numerator, | ||
1665 | sp->parm.capture.timeperframe.denominator, fdec); | ||
1666 | return 0; | ||
1667 | } | ||
1526 | 1668 | ||
1527 | dev->cap_parm[fh->channel].capturemode = sp->parm.capture.capturemode; | 1669 | static int vidioc_enum_frameintervals(struct file *file, void *priv, |
1528 | dprintk(2, "setting param capture mode %d\n", | 1670 | struct v4l2_frmivalenum *fe) |
1529 | sp->parm.capture.capturemode); | 1671 | { |
1672 | int is_ntsc = 0; | ||
1673 | #define NUM_FRAME_ENUMS 4 | ||
1674 | int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5}; | ||
1675 | if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS) | ||
1676 | return -EINVAL; | ||
1677 | switch (fe->width) { | ||
1678 | case 640: | ||
1679 | if (fe->height != 240 && fe->height != 480) | ||
1680 | return -EINVAL; | ||
1681 | is_ntsc = 1; | ||
1682 | break; | ||
1683 | case 320: | ||
1684 | if (fe->height != 240) | ||
1685 | return -EINVAL; | ||
1686 | is_ntsc = 1; | ||
1687 | break; | ||
1688 | case 704: | ||
1689 | if (fe->height != 288 && fe->height != 576) | ||
1690 | return -EINVAL; | ||
1691 | break; | ||
1692 | case 352: | ||
1693 | if (fe->height != 288) | ||
1694 | return -EINVAL; | ||
1695 | break; | ||
1696 | default: | ||
1697 | return -EINVAL; | ||
1698 | } | ||
1699 | fe->type = V4L2_FRMIVAL_TYPE_DISCRETE; | ||
1700 | fe->discrete.denominator = is_ntsc ? 30000 : 25000; | ||
1701 | fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index]; | ||
1702 | dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator, | ||
1703 | fe->discrete.denominator); | ||
1530 | return 0; | 1704 | return 0; |
1531 | } | 1705 | } |
1706 | |||
1532 | static int s2255_open(struct file *file) | 1707 | static int s2255_open(struct file *file) |
1533 | { | 1708 | { |
1534 | struct video_device *vdev = video_devdata(file); | 1709 | struct video_device *vdev = video_devdata(file); |
@@ -1538,31 +1713,29 @@ static int s2255_open(struct file *file) | |||
1538 | int i = 0; | 1713 | int i = 0; |
1539 | int cur_channel = -1; | 1714 | int cur_channel = -1; |
1540 | int state; | 1715 | int state; |
1541 | |||
1542 | dprintk(1, "s2255: open called (dev=%s)\n", | 1716 | dprintk(1, "s2255: open called (dev=%s)\n", |
1543 | video_device_node_name(vdev)); | 1717 | video_device_node_name(vdev)); |
1544 | 1718 | ||
1545 | lock_kernel(); | ||
1546 | |||
1547 | for (i = 0; i < MAX_CHANNELS; i++) { | 1719 | for (i = 0; i < MAX_CHANNELS; i++) { |
1548 | if (dev->vdev[i] == vdev) { | 1720 | if (&dev->vdev[i] == vdev) { |
1549 | cur_channel = i; | 1721 | cur_channel = i; |
1550 | break; | 1722 | break; |
1551 | } | 1723 | } |
1552 | } | 1724 | } |
1553 | 1725 | if (i == MAX_CHANNELS) | |
1554 | if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_DISCONNECTING) { | ||
1555 | unlock_kernel(); | ||
1556 | printk(KERN_INFO "disconnecting\n"); | ||
1557 | return -ENODEV; | 1726 | return -ENODEV; |
1558 | } | ||
1559 | kref_get(&dev->kref); | ||
1560 | mutex_lock(&dev->open_lock); | ||
1561 | |||
1562 | dev->users[cur_channel]++; | ||
1563 | dprintk(4, "s2255: open_handles %d\n", dev->users[cur_channel]); | ||
1564 | 1727 | ||
1565 | switch (atomic_read(&dev->fw_data->fw_state)) { | 1728 | /* |
1729 | * open lock necessary to prevent multiple instances | ||
1730 | * of v4l-conf (or other programs) from simultaneously | ||
1731 | * reloading firmware. | ||
1732 | */ | ||
1733 | mutex_lock(&dev->open_lock); | ||
1734 | state = atomic_read(&dev->fw_data->fw_state); | ||
1735 | switch (state) { | ||
1736 | case S2255_FW_DISCONNECTING: | ||
1737 | mutex_unlock(&dev->open_lock); | ||
1738 | return -ENODEV; | ||
1566 | case S2255_FW_FAILED: | 1739 | case S2255_FW_FAILED: |
1567 | s2255_dev_err(&dev->udev->dev, | 1740 | s2255_dev_err(&dev->udev->dev, |
1568 | "firmware load failed. retrying.\n"); | 1741 | "firmware load failed. retrying.\n"); |
@@ -1573,6 +1746,8 @@ static int s2255_open(struct file *file) | |||
1573 | (atomic_read(&dev->fw_data->fw_state) | 1746 | (atomic_read(&dev->fw_data->fw_state) |
1574 | == S2255_FW_DISCONNECTING)), | 1747 | == S2255_FW_DISCONNECTING)), |
1575 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); | 1748 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); |
1749 | /* state may have changed, re-read */ | ||
1750 | state = atomic_read(&dev->fw_data->fw_state); | ||
1576 | break; | 1751 | break; |
1577 | case S2255_FW_NOTLOADED: | 1752 | case S2255_FW_NOTLOADED: |
1578 | case S2255_FW_LOADED_DSPWAIT: | 1753 | case S2255_FW_LOADED_DSPWAIT: |
@@ -1584,53 +1759,50 @@ static int s2255_open(struct file *file) | |||
1584 | == S2255_FW_SUCCESS) || | 1759 | == S2255_FW_SUCCESS) || |
1585 | (atomic_read(&dev->fw_data->fw_state) | 1760 | (atomic_read(&dev->fw_data->fw_state) |
1586 | == S2255_FW_DISCONNECTING)), | 1761 | == S2255_FW_DISCONNECTING)), |
1587 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); | 1762 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); |
1763 | /* state may have changed, re-read */ | ||
1764 | state = atomic_read(&dev->fw_data->fw_state); | ||
1588 | break; | 1765 | break; |
1589 | case S2255_FW_SUCCESS: | 1766 | case S2255_FW_SUCCESS: |
1590 | default: | 1767 | default: |
1591 | break; | 1768 | break; |
1592 | } | 1769 | } |
1593 | state = atomic_read(&dev->fw_data->fw_state); | 1770 | /* state may have changed in above switch statement */ |
1594 | if (state != S2255_FW_SUCCESS) { | 1771 | switch (state) { |
1595 | int rc; | 1772 | case S2255_FW_SUCCESS: |
1596 | switch (state) { | 1773 | break; |
1597 | case S2255_FW_FAILED: | 1774 | case S2255_FW_FAILED: |
1598 | printk(KERN_INFO "2255 FW load failed. %d\n", state); | 1775 | printk(KERN_INFO "2255 firmware load failed.\n"); |
1599 | rc = -ENODEV; | 1776 | mutex_unlock(&dev->open_lock); |
1600 | break; | 1777 | return -ENODEV; |
1601 | case S2255_FW_DISCONNECTING: | 1778 | case S2255_FW_DISCONNECTING: |
1602 | printk(KERN_INFO "%s: disconnecting\n", __func__); | 1779 | printk(KERN_INFO "%s: disconnecting\n", __func__); |
1603 | rc = -ENODEV; | ||
1604 | break; | ||
1605 | case S2255_FW_LOADED_DSPWAIT: | ||
1606 | case S2255_FW_NOTLOADED: | ||
1607 | printk(KERN_INFO "%s: firmware not loaded yet" | ||
1608 | "please try again later\n", | ||
1609 | __func__); | ||
1610 | rc = -EAGAIN; | ||
1611 | break; | ||
1612 | default: | ||
1613 | printk(KERN_INFO "%s: unknown state\n", __func__); | ||
1614 | rc = -EFAULT; | ||
1615 | break; | ||
1616 | } | ||
1617 | dev->users[cur_channel]--; | ||
1618 | mutex_unlock(&dev->open_lock); | 1780 | mutex_unlock(&dev->open_lock); |
1619 | kref_put(&dev->kref, s2255_destroy); | 1781 | return -ENODEV; |
1620 | unlock_kernel(); | 1782 | case S2255_FW_LOADED_DSPWAIT: |
1621 | return rc; | 1783 | case S2255_FW_NOTLOADED: |
1784 | printk(KERN_INFO "%s: firmware not loaded yet" | ||
1785 | "please try again later\n", | ||
1786 | __func__); | ||
1787 | /* | ||
1788 | * Timeout on firmware load means device unusable. | ||
1789 | * Set firmware failure state. | ||
1790 | * On next s2255_open the firmware will be reloaded. | ||
1791 | */ | ||
1792 | atomic_set(&dev->fw_data->fw_state, | ||
1793 | S2255_FW_FAILED); | ||
1794 | mutex_unlock(&dev->open_lock); | ||
1795 | return -EAGAIN; | ||
1796 | default: | ||
1797 | printk(KERN_INFO "%s: unknown state\n", __func__); | ||
1798 | mutex_unlock(&dev->open_lock); | ||
1799 | return -EFAULT; | ||
1622 | } | 1800 | } |
1623 | 1801 | mutex_unlock(&dev->open_lock); | |
1624 | /* allocate + initialize per filehandle data */ | 1802 | /* allocate + initialize per filehandle data */ |
1625 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 1803 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
1626 | if (NULL == fh) { | 1804 | if (NULL == fh) |
1627 | dev->users[cur_channel]--; | ||
1628 | mutex_unlock(&dev->open_lock); | ||
1629 | kref_put(&dev->kref, s2255_destroy); | ||
1630 | unlock_kernel(); | ||
1631 | return -ENOMEM; | 1805 | return -ENOMEM; |
1632 | } | ||
1633 | |||
1634 | file->private_data = fh; | 1806 | file->private_data = fh; |
1635 | fh->dev = dev; | 1807 | fh->dev = dev; |
1636 | fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1808 | fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
@@ -1640,35 +1812,23 @@ static int s2255_open(struct file *file) | |||
1640 | fh->width = LINE_SZ_4CIFS_NTSC; | 1812 | fh->width = LINE_SZ_4CIFS_NTSC; |
1641 | fh->height = NUM_LINES_4CIFS_NTSC * 2; | 1813 | fh->height = NUM_LINES_4CIFS_NTSC * 2; |
1642 | fh->channel = cur_channel; | 1814 | fh->channel = cur_channel; |
1643 | |||
1644 | /* configure channel to default state */ | 1815 | /* configure channel to default state */ |
1645 | if (!dev->chn_configured[cur_channel]) { | 1816 | if (!dev->chn_configured[cur_channel]) { |
1646 | s2255_set_mode(dev, cur_channel, &fh->mode); | 1817 | s2255_set_mode(dev, cur_channel, &fh->mode); |
1647 | dev->chn_configured[cur_channel] = 1; | 1818 | dev->chn_configured[cur_channel] = 1; |
1648 | } | 1819 | } |
1649 | 1820 | dprintk(1, "%s: dev=%s type=%s\n", __func__, | |
1650 | 1821 | video_device_node_name(vdev), v4l2_type_names[type]); | |
1651 | /* Put all controls at a sane state */ | 1822 | dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__, |
1652 | for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) | ||
1653 | qctl_regs[i] = s2255_qctrl[i].default_value; | ||
1654 | |||
1655 | dprintk(1, "s2255drv: open dev=%s type=%s users=%d\n", | ||
1656 | video_device_node_name(vdev), v4l2_type_names[type], | ||
1657 | dev->users[cur_channel]); | ||
1658 | dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", | ||
1659 | (unsigned long)fh, (unsigned long)dev, | 1823 | (unsigned long)fh, (unsigned long)dev, |
1660 | (unsigned long)&dev->vidq[cur_channel]); | 1824 | (unsigned long)&dev->vidq[cur_channel]); |
1661 | dprintk(4, "s2255drv: open: list_empty active=%d\n", | 1825 | dprintk(4, "%s: list_empty active=%d\n", __func__, |
1662 | list_empty(&dev->vidq[cur_channel].active)); | 1826 | list_empty(&dev->vidq[cur_channel].active)); |
1663 | |||
1664 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops, | 1827 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops, |
1665 | NULL, &dev->slock, | 1828 | NULL, &dev->slock, |
1666 | fh->type, | 1829 | fh->type, |
1667 | V4L2_FIELD_INTERLACED, | 1830 | V4L2_FIELD_INTERLACED, |
1668 | sizeof(struct s2255_buffer), fh); | 1831 | sizeof(struct s2255_buffer), fh); |
1669 | |||
1670 | mutex_unlock(&dev->open_lock); | ||
1671 | unlock_kernel(); | ||
1672 | return 0; | 1832 | return 0; |
1673 | } | 1833 | } |
1674 | 1834 | ||
@@ -1679,39 +1839,19 @@ static unsigned int s2255_poll(struct file *file, | |||
1679 | struct s2255_fh *fh = file->private_data; | 1839 | struct s2255_fh *fh = file->private_data; |
1680 | int rc; | 1840 | int rc; |
1681 | dprintk(100, "%s\n", __func__); | 1841 | dprintk(100, "%s\n", __func__); |
1682 | |||
1683 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) | 1842 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) |
1684 | return POLLERR; | 1843 | return POLLERR; |
1685 | |||
1686 | rc = videobuf_poll_stream(file, &fh->vb_vidq, wait); | 1844 | rc = videobuf_poll_stream(file, &fh->vb_vidq, wait); |
1687 | return rc; | 1845 | return rc; |
1688 | } | 1846 | } |
1689 | 1847 | ||
1690 | static void s2255_destroy(struct kref *kref) | 1848 | static void s2255_destroy(struct s2255_dev *dev) |
1691 | { | 1849 | { |
1692 | struct s2255_dev *dev = to_s2255_dev(kref); | ||
1693 | int i; | ||
1694 | if (!dev) { | ||
1695 | printk(KERN_ERR "s2255drv: kref problem\n"); | ||
1696 | return; | ||
1697 | } | ||
1698 | atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); | ||
1699 | wake_up(&dev->fw_data->wait_fw); | ||
1700 | for (i = 0; i < MAX_CHANNELS; i++) { | ||
1701 | dev->setmode_ready[i] = 1; | ||
1702 | wake_up(&dev->wait_setmode[i]); | ||
1703 | } | ||
1704 | mutex_lock(&dev->open_lock); | ||
1705 | /* reset the DSP so firmware can be reload next time */ | ||
1706 | s2255_reset_dsppower(dev); | ||
1707 | s2255_exit_v4l(dev); | ||
1708 | /* board shutdown stops the read pipe if it is running */ | 1850 | /* board shutdown stops the read pipe if it is running */ |
1709 | s2255_board_shutdown(dev); | 1851 | s2255_board_shutdown(dev); |
1710 | /* make sure firmware still not trying to load */ | 1852 | /* make sure firmware still not trying to load */ |
1711 | del_timer(&dev->timer); /* only started in .probe and .open */ | 1853 | del_timer(&dev->timer); /* only started in .probe and .open */ |
1712 | |||
1713 | if (dev->fw_data->fw_urb) { | 1854 | if (dev->fw_data->fw_urb) { |
1714 | dprintk(2, "kill fw_urb\n"); | ||
1715 | usb_kill_urb(dev->fw_data->fw_urb); | 1855 | usb_kill_urb(dev->fw_data->fw_urb); |
1716 | usb_free_urb(dev->fw_data->fw_urb); | 1856 | usb_free_urb(dev->fw_data->fw_urb); |
1717 | dev->fw_data->fw_urb = NULL; | 1857 | dev->fw_data->fw_urb = NULL; |
@@ -1720,24 +1860,22 @@ static void s2255_destroy(struct kref *kref) | |||
1720 | release_firmware(dev->fw_data->fw); | 1860 | release_firmware(dev->fw_data->fw); |
1721 | kfree(dev->fw_data->pfw_data); | 1861 | kfree(dev->fw_data->pfw_data); |
1722 | kfree(dev->fw_data); | 1862 | kfree(dev->fw_data); |
1863 | /* reset the DSP so firmware can be reloaded next time */ | ||
1864 | s2255_reset_dsppower(dev); | ||
1865 | mutex_destroy(&dev->open_lock); | ||
1866 | mutex_destroy(&dev->lock); | ||
1723 | usb_put_dev(dev->udev); | 1867 | usb_put_dev(dev->udev); |
1724 | dprintk(1, "%s", __func__); | 1868 | dprintk(1, "%s", __func__); |
1725 | |||
1726 | mutex_unlock(&dev->open_lock); | ||
1727 | kfree(dev); | 1869 | kfree(dev); |
1728 | } | 1870 | } |
1729 | 1871 | ||
1730 | static int s2255_close(struct file *file) | 1872 | static int s2255_release(struct file *file) |
1731 | { | 1873 | { |
1732 | struct s2255_fh *fh = file->private_data; | 1874 | struct s2255_fh *fh = file->private_data; |
1733 | struct s2255_dev *dev = fh->dev; | 1875 | struct s2255_dev *dev = fh->dev; |
1734 | struct video_device *vdev = video_devdata(file); | 1876 | struct video_device *vdev = video_devdata(file); |
1735 | |||
1736 | if (!dev) | 1877 | if (!dev) |
1737 | return -ENODEV; | 1878 | return -ENODEV; |
1738 | |||
1739 | mutex_lock(&dev->open_lock); | ||
1740 | |||
1741 | /* turn off stream */ | 1879 | /* turn off stream */ |
1742 | if (res_check(fh)) { | 1880 | if (res_check(fh)) { |
1743 | if (dev->b_acquire[fh->channel]) | 1881 | if (dev->b_acquire[fh->channel]) |
@@ -1745,15 +1883,8 @@ static int s2255_close(struct file *file) | |||
1745 | videobuf_streamoff(&fh->vb_vidq); | 1883 | videobuf_streamoff(&fh->vb_vidq); |
1746 | res_free(dev, fh); | 1884 | res_free(dev, fh); |
1747 | } | 1885 | } |
1748 | |||
1749 | videobuf_mmap_free(&fh->vb_vidq); | 1886 | videobuf_mmap_free(&fh->vb_vidq); |
1750 | dev->users[fh->channel]--; | 1887 | dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev)); |
1751 | |||
1752 | mutex_unlock(&dev->open_lock); | ||
1753 | |||
1754 | kref_put(&dev->kref, s2255_destroy); | ||
1755 | dprintk(1, "s2255: close called (dev=%s, users=%d)\n", | ||
1756 | video_device_node_name(vdev), dev->users[fh->channel]); | ||
1757 | kfree(fh); | 1888 | kfree(fh); |
1758 | return 0; | 1889 | return 0; |
1759 | } | 1890 | } |
@@ -1765,27 +1896,25 @@ static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma) | |||
1765 | 1896 | ||
1766 | if (!fh) | 1897 | if (!fh) |
1767 | return -ENODEV; | 1898 | return -ENODEV; |
1768 | dprintk(4, "mmap called, vma=0x%08lx\n", (unsigned long)vma); | 1899 | dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma); |
1769 | |||
1770 | ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); | 1900 | ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); |
1771 | 1901 | dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__, | |
1772 | dprintk(4, "vma start=0x%08lx, size=%ld, ret=%d\n", | ||
1773 | (unsigned long)vma->vm_start, | 1902 | (unsigned long)vma->vm_start, |
1774 | (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret); | 1903 | (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret); |
1775 | |||
1776 | return ret; | 1904 | return ret; |
1777 | } | 1905 | } |
1778 | 1906 | ||
1779 | static const struct v4l2_file_operations s2255_fops_v4l = { | 1907 | static const struct v4l2_file_operations s2255_fops_v4l = { |
1780 | .owner = THIS_MODULE, | 1908 | .owner = THIS_MODULE, |
1781 | .open = s2255_open, | 1909 | .open = s2255_open, |
1782 | .release = s2255_close, | 1910 | .release = s2255_release, |
1783 | .poll = s2255_poll, | 1911 | .poll = s2255_poll, |
1784 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ | 1912 | .ioctl = video_ioctl2, /* V4L2 ioctl handler */ |
1785 | .mmap = s2255_mmap_v4l, | 1913 | .mmap = s2255_mmap_v4l, |
1786 | }; | 1914 | }; |
1787 | 1915 | ||
1788 | static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | 1916 | static const struct v4l2_ioctl_ops s2255_ioctl_ops = { |
1917 | .vidioc_querymenu = vidioc_querymenu, | ||
1789 | .vidioc_querycap = vidioc_querycap, | 1918 | .vidioc_querycap = vidioc_querycap, |
1790 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | 1919 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, |
1791 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | 1920 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, |
@@ -1811,13 +1940,23 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | |||
1811 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, | 1940 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, |
1812 | .vidioc_s_parm = vidioc_s_parm, | 1941 | .vidioc_s_parm = vidioc_s_parm, |
1813 | .vidioc_g_parm = vidioc_g_parm, | 1942 | .vidioc_g_parm = vidioc_g_parm, |
1943 | .vidioc_enum_frameintervals = vidioc_enum_frameintervals, | ||
1814 | }; | 1944 | }; |
1815 | 1945 | ||
1946 | static void s2255_video_device_release(struct video_device *vdev) | ||
1947 | { | ||
1948 | struct s2255_dev *dev = video_get_drvdata(vdev); | ||
1949 | dprintk(4, "%s, chnls: %d \n", __func__, atomic_read(&dev->channels)); | ||
1950 | if (atomic_dec_and_test(&dev->channels)) | ||
1951 | s2255_destroy(dev); | ||
1952 | return; | ||
1953 | } | ||
1954 | |||
1816 | static struct video_device template = { | 1955 | static struct video_device template = { |
1817 | .name = "s2255v", | 1956 | .name = "s2255v", |
1818 | .fops = &s2255_fops_v4l, | 1957 | .fops = &s2255_fops_v4l, |
1819 | .ioctl_ops = &s2255_ioctl_ops, | 1958 | .ioctl_ops = &s2255_ioctl_ops, |
1820 | .release = video_device_release, | 1959 | .release = s2255_video_device_release, |
1821 | .tvnorms = S2255_NORMS, | 1960 | .tvnorms = S2255_NORMS, |
1822 | .current_norm = V4L2_STD_NTSC_M, | 1961 | .current_norm = V4L2_STD_NTSC_M, |
1823 | }; | 1962 | }; |
@@ -1827,7 +1966,9 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
1827 | int ret; | 1966 | int ret; |
1828 | int i; | 1967 | int i; |
1829 | int cur_nr = video_nr; | 1968 | int cur_nr = video_nr; |
1830 | 1969 | ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev); | |
1970 | if (ret) | ||
1971 | return ret; | ||
1831 | /* initialize all video 4 linux */ | 1972 | /* initialize all video 4 linux */ |
1832 | /* register 4 video devices */ | 1973 | /* register 4 video devices */ |
1833 | for (i = 0; i < MAX_CHANNELS; i++) { | 1974 | for (i = 0; i < MAX_CHANNELS; i++) { |
@@ -1835,45 +1976,39 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
1835 | dev->vidq[i].dev = dev; | 1976 | dev->vidq[i].dev = dev; |
1836 | dev->vidq[i].channel = i; | 1977 | dev->vidq[i].channel = i; |
1837 | /* register 4 video devices */ | 1978 | /* register 4 video devices */ |
1838 | dev->vdev[i] = video_device_alloc(); | 1979 | memcpy(&dev->vdev[i], &template, sizeof(struct video_device)); |
1839 | memcpy(dev->vdev[i], &template, sizeof(struct video_device)); | 1980 | dev->vdev[i].v4l2_dev = &dev->v4l2_dev; |
1840 | dev->vdev[i]->parent = &dev->interface->dev; | 1981 | video_set_drvdata(&dev->vdev[i], dev); |
1841 | video_set_drvdata(dev->vdev[i], dev); | ||
1842 | if (video_nr == -1) | 1982 | if (video_nr == -1) |
1843 | ret = video_register_device(dev->vdev[i], | 1983 | ret = video_register_device(&dev->vdev[i], |
1844 | VFL_TYPE_GRABBER, | 1984 | VFL_TYPE_GRABBER, |
1845 | video_nr); | 1985 | video_nr); |
1846 | else | 1986 | else |
1847 | ret = video_register_device(dev->vdev[i], | 1987 | ret = video_register_device(&dev->vdev[i], |
1848 | VFL_TYPE_GRABBER, | 1988 | VFL_TYPE_GRABBER, |
1849 | cur_nr + i); | 1989 | cur_nr + i); |
1850 | video_set_drvdata(dev->vdev[i], dev); | 1990 | if (ret) { |
1851 | |||
1852 | if (ret != 0) { | ||
1853 | dev_err(&dev->udev->dev, | 1991 | dev_err(&dev->udev->dev, |
1854 | "failed to register video device!\n"); | 1992 | "failed to register video device!\n"); |
1855 | return ret; | 1993 | break; |
1856 | } | 1994 | } |
1995 | atomic_inc(&dev->channels); | ||
1996 | v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n", | ||
1997 | video_device_node_name(&dev->vdev[i])); | ||
1998 | |||
1857 | } | 1999 | } |
2000 | |||
1858 | printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n", | 2001 | printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n", |
1859 | S2255_MAJOR_VERSION, | 2002 | S2255_MAJOR_VERSION, |
1860 | S2255_MINOR_VERSION); | 2003 | S2255_MINOR_VERSION); |
1861 | return ret; | 2004 | /* if no channels registered, return error and probe will fail*/ |
1862 | } | 2005 | if (atomic_read(&dev->channels) == 0) { |
1863 | 2006 | v4l2_device_unregister(&dev->v4l2_dev); | |
1864 | static void s2255_exit_v4l(struct s2255_dev *dev) | 2007 | return ret; |
1865 | { | ||
1866 | |||
1867 | int i; | ||
1868 | for (i = 0; i < MAX_CHANNELS; i++) { | ||
1869 | if (video_is_registered(dev->vdev[i])) { | ||
1870 | video_unregister_device(dev->vdev[i]); | ||
1871 | printk(KERN_INFO "s2255 unregistered\n"); | ||
1872 | } else { | ||
1873 | video_device_release(dev->vdev[i]); | ||
1874 | printk(KERN_INFO "s2255 released\n"); | ||
1875 | } | ||
1876 | } | 2008 | } |
2009 | if (atomic_read(&dev->channels) != MAX_CHANNELS) | ||
2010 | printk(KERN_WARNING "s2255: Not all channels available.\n"); | ||
2011 | return 0; | ||
1877 | } | 2012 | } |
1878 | 2013 | ||
1879 | /* this function moves the usb stream read pipe data | 2014 | /* this function moves the usb stream read pipe data |
@@ -1907,14 +2042,14 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) | |||
1907 | if (frm->ulState == S2255_READ_IDLE) { | 2042 | if (frm->ulState == S2255_READ_IDLE) { |
1908 | int jj; | 2043 | int jj; |
1909 | unsigned int cc; | 2044 | unsigned int cc; |
1910 | s32 *pdword; | 2045 | __le32 *pdword; /*data from dsp is little endian */ |
1911 | int payload; | 2046 | int payload; |
1912 | /* search for marker codes */ | 2047 | /* search for marker codes */ |
1913 | pdata = (unsigned char *)pipe_info->transfer_buffer; | 2048 | pdata = (unsigned char *)pipe_info->transfer_buffer; |
2049 | pdword = (__le32 *)pdata; | ||
1914 | for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) { | 2050 | for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) { |
1915 | switch (*(s32 *) pdata) { | 2051 | switch (*pdword) { |
1916 | case S2255_MARKER_FRAME: | 2052 | case S2255_MARKER_FRAME: |
1917 | pdword = (s32 *)pdata; | ||
1918 | dprintk(4, "found frame marker at offset:" | 2053 | dprintk(4, "found frame marker at offset:" |
1919 | " %d [%x %x]\n", jj, pdata[0], | 2054 | " %d [%x %x]\n", jj, pdata[0], |
1920 | pdata[1]); | 2055 | pdata[1]); |
@@ -1938,7 +2073,6 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) | |||
1938 | dev->jpg_size[dev->cc] = pdword[4]; | 2073 | dev->jpg_size[dev->cc] = pdword[4]; |
1939 | break; | 2074 | break; |
1940 | case S2255_MARKER_RESPONSE: | 2075 | case S2255_MARKER_RESPONSE: |
1941 | pdword = (s32 *)pdata; | ||
1942 | pdata += DEF_USB_BLOCK; | 2076 | pdata += DEF_USB_BLOCK; |
1943 | jj += DEF_USB_BLOCK; | 2077 | jj += DEF_USB_BLOCK; |
1944 | if (pdword[1] >= MAX_CHANNELS) | 2078 | if (pdword[1] >= MAX_CHANNELS) |
@@ -1955,7 +2089,6 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) | |||
1955 | dprintk(5, "setmode ready %d\n", cc); | 2089 | dprintk(5, "setmode ready %d\n", cc); |
1956 | break; | 2090 | break; |
1957 | case S2255_RESPONSE_FW: | 2091 | case S2255_RESPONSE_FW: |
1958 | |||
1959 | dev->chn_ready |= (1 << cc); | 2092 | dev->chn_ready |= (1 << cc); |
1960 | if ((dev->chn_ready & 0x0f) != 0x0f) | 2093 | if ((dev->chn_ready & 0x0f) != 0x0f) |
1961 | break; | 2094 | break; |
@@ -1965,6 +2098,13 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) | |||
1965 | S2255_FW_SUCCESS); | 2098 | S2255_FW_SUCCESS); |
1966 | wake_up(&dev->fw_data->wait_fw); | 2099 | wake_up(&dev->fw_data->wait_fw); |
1967 | break; | 2100 | break; |
2101 | case S2255_RESPONSE_STATUS: | ||
2102 | dev->vidstatus[cc] = pdword[3]; | ||
2103 | dev->vidstatus_ready[cc] = 1; | ||
2104 | wake_up(&dev->wait_vidstatus[cc]); | ||
2105 | dprintk(5, "got vidstatus %x chan %d\n", | ||
2106 | pdword[3], cc); | ||
2107 | break; | ||
1968 | default: | 2108 | default: |
1969 | printk(KERN_INFO "s2255 unknown resp\n"); | 2109 | printk(KERN_INFO "s2255 unknown resp\n"); |
1970 | } | 2110 | } |
@@ -2165,28 +2305,22 @@ static int s2255_release_sys_buffers(struct s2255_dev *dev, | |||
2165 | 2305 | ||
2166 | static int s2255_board_init(struct s2255_dev *dev) | 2306 | static int s2255_board_init(struct s2255_dev *dev) |
2167 | { | 2307 | { |
2168 | int j; | ||
2169 | struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT; | 2308 | struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT; |
2170 | int fw_ver; | 2309 | int fw_ver; |
2310 | int j; | ||
2311 | struct s2255_pipeinfo *pipe = &dev->pipe; | ||
2171 | dprintk(4, "board init: %p", dev); | 2312 | dprintk(4, "board init: %p", dev); |
2172 | 2313 | memset(pipe, 0, sizeof(*pipe)); | |
2173 | for (j = 0; j < MAX_PIPE_BUFFERS; j++) { | 2314 | pipe->dev = dev; |
2174 | struct s2255_pipeinfo *pipe = &dev->pipes[j]; | 2315 | pipe->cur_transfer_size = S2255_USB_XFER_SIZE; |
2175 | 2316 | pipe->max_transfer_size = S2255_USB_XFER_SIZE; | |
2176 | memset(pipe, 0, sizeof(*pipe)); | 2317 | |
2177 | pipe->dev = dev; | 2318 | pipe->transfer_buffer = kzalloc(pipe->max_transfer_size, |
2178 | pipe->cur_transfer_size = S2255_USB_XFER_SIZE; | 2319 | GFP_KERNEL); |
2179 | pipe->max_transfer_size = S2255_USB_XFER_SIZE; | 2320 | if (pipe->transfer_buffer == NULL) { |
2180 | 2321 | dprintk(1, "out of memory!\n"); | |
2181 | pipe->transfer_buffer = kzalloc(pipe->max_transfer_size, | 2322 | return -ENOMEM; |
2182 | GFP_KERNEL); | ||
2183 | if (pipe->transfer_buffer == NULL) { | ||
2184 | dprintk(1, "out of memory!\n"); | ||
2185 | return -ENOMEM; | ||
2186 | } | ||
2187 | |||
2188 | } | 2323 | } |
2189 | |||
2190 | /* query the firmware */ | 2324 | /* query the firmware */ |
2191 | fw_ver = s2255_get_fx2fw(dev); | 2325 | fw_ver = s2255_get_fx2fw(dev); |
2192 | 2326 | ||
@@ -2203,6 +2337,8 @@ static int s2255_board_init(struct s2255_dev *dev) | |||
2203 | for (j = 0; j < MAX_CHANNELS; j++) { | 2337 | for (j = 0; j < MAX_CHANNELS; j++) { |
2204 | dev->b_acquire[j] = 0; | 2338 | dev->b_acquire[j] = 0; |
2205 | dev->mode[j] = mode_def; | 2339 | dev->mode[j] = mode_def; |
2340 | if (dev->pid == 0x2257 && j > 1) | ||
2341 | dev->mode[j].color |= (1 << 16); | ||
2206 | dev->jc[j].quality = S2255_DEF_JPEG_QUAL; | 2342 | dev->jc[j].quality = S2255_DEF_JPEG_QUAL; |
2207 | dev->cur_fmt[j] = &formats[0]; | 2343 | dev->cur_fmt[j] = &formats[0]; |
2208 | dev->mode[j].restart = 1; | 2344 | dev->mode[j].restart = 1; |
@@ -2213,16 +2349,14 @@ static int s2255_board_init(struct s2255_dev *dev) | |||
2213 | } | 2349 | } |
2214 | /* start read pipe */ | 2350 | /* start read pipe */ |
2215 | s2255_start_readpipe(dev); | 2351 | s2255_start_readpipe(dev); |
2216 | 2352 | dprintk(1, "%s: success\n", __func__); | |
2217 | dprintk(1, "S2255: board initialized\n"); | ||
2218 | return 0; | 2353 | return 0; |
2219 | } | 2354 | } |
2220 | 2355 | ||
2221 | static int s2255_board_shutdown(struct s2255_dev *dev) | 2356 | static int s2255_board_shutdown(struct s2255_dev *dev) |
2222 | { | 2357 | { |
2223 | u32 i; | 2358 | u32 i; |
2224 | 2359 | dprintk(1, "%s: dev: %p", __func__, dev); | |
2225 | dprintk(1, "S2255: board shutdown: %p", dev); | ||
2226 | 2360 | ||
2227 | for (i = 0; i < MAX_CHANNELS; i++) { | 2361 | for (i = 0; i < MAX_CHANNELS; i++) { |
2228 | if (dev->b_acquire[i]) | 2362 | if (dev->b_acquire[i]) |
@@ -2233,12 +2367,8 @@ static int s2255_board_shutdown(struct s2255_dev *dev) | |||
2233 | 2367 | ||
2234 | for (i = 0; i < MAX_CHANNELS; i++) | 2368 | for (i = 0; i < MAX_CHANNELS; i++) |
2235 | s2255_release_sys_buffers(dev, i); | 2369 | s2255_release_sys_buffers(dev, i); |
2236 | 2370 | /* release transfer buffer */ | |
2237 | /* release transfer buffers */ | 2371 | kfree(dev->pipe.transfer_buffer); |
2238 | for (i = 0; i < MAX_PIPE_BUFFERS; i++) { | ||
2239 | struct s2255_pipeinfo *pipe = &dev->pipes[i]; | ||
2240 | kfree(pipe->transfer_buffer); | ||
2241 | } | ||
2242 | return 0; | 2372 | return 0; |
2243 | } | 2373 | } |
2244 | 2374 | ||
@@ -2248,9 +2378,8 @@ static void read_pipe_completion(struct urb *purb) | |||
2248 | struct s2255_dev *dev; | 2378 | struct s2255_dev *dev; |
2249 | int status; | 2379 | int status; |
2250 | int pipe; | 2380 | int pipe; |
2251 | |||
2252 | pipe_info = purb->context; | 2381 | pipe_info = purb->context; |
2253 | dprintk(100, "read pipe completion %p, status %d\n", purb, | 2382 | dprintk(100, "%s: urb:%p, status %d\n", __func__, purb, |
2254 | purb->status); | 2383 | purb->status); |
2255 | if (pipe_info == NULL) { | 2384 | if (pipe_info == NULL) { |
2256 | dev_err(&purb->dev->dev, "no context!\n"); | 2385 | dev_err(&purb->dev->dev, "no context!\n"); |
@@ -2265,13 +2394,13 @@ static void read_pipe_completion(struct urb *purb) | |||
2265 | status = purb->status; | 2394 | status = purb->status; |
2266 | /* if shutting down, do not resubmit, exit immediately */ | 2395 | /* if shutting down, do not resubmit, exit immediately */ |
2267 | if (status == -ESHUTDOWN) { | 2396 | if (status == -ESHUTDOWN) { |
2268 | dprintk(2, "read_pipe_completion: err shutdown\n"); | 2397 | dprintk(2, "%s: err shutdown\n", __func__); |
2269 | pipe_info->err_count++; | 2398 | pipe_info->err_count++; |
2270 | return; | 2399 | return; |
2271 | } | 2400 | } |
2272 | 2401 | ||
2273 | if (pipe_info->state == 0) { | 2402 | if (pipe_info->state == 0) { |
2274 | dprintk(2, "exiting USB pipe"); | 2403 | dprintk(2, "%s: exiting USB pipe", __func__); |
2275 | return; | 2404 | return; |
2276 | } | 2405 | } |
2277 | 2406 | ||
@@ -2279,7 +2408,7 @@ static void read_pipe_completion(struct urb *purb) | |||
2279 | s2255_read_video_callback(dev, pipe_info); | 2408 | s2255_read_video_callback(dev, pipe_info); |
2280 | else { | 2409 | else { |
2281 | pipe_info->err_count++; | 2410 | pipe_info->err_count++; |
2282 | dprintk(1, "s2255drv: failed URB %d\n", status); | 2411 | dprintk(1, "%s: failed URB %d\n", __func__, status); |
2283 | } | 2412 | } |
2284 | 2413 | ||
2285 | pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); | 2414 | pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); |
@@ -2295,7 +2424,7 @@ static void read_pipe_completion(struct urb *purb) | |||
2295 | dev_err(&dev->udev->dev, "error submitting urb\n"); | 2424 | dev_err(&dev->udev->dev, "error submitting urb\n"); |
2296 | } | 2425 | } |
2297 | } else { | 2426 | } else { |
2298 | dprintk(2, "read pipe complete state 0\n"); | 2427 | dprintk(2, "%s :complete state 0\n", __func__); |
2299 | } | 2428 | } |
2300 | return; | 2429 | return; |
2301 | } | 2430 | } |
@@ -2304,35 +2433,28 @@ static int s2255_start_readpipe(struct s2255_dev *dev) | |||
2304 | { | 2433 | { |
2305 | int pipe; | 2434 | int pipe; |
2306 | int retval; | 2435 | int retval; |
2307 | int i; | 2436 | struct s2255_pipeinfo *pipe_info = &dev->pipe; |
2308 | struct s2255_pipeinfo *pipe_info = dev->pipes; | ||
2309 | pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); | 2437 | pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); |
2310 | dprintk(2, "start pipe IN %d\n", dev->read_endpoint); | 2438 | dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint); |
2311 | 2439 | pipe_info->state = 1; | |
2312 | for (i = 0; i < MAX_PIPE_BUFFERS; i++) { | 2440 | pipe_info->err_count = 0; |
2313 | pipe_info->state = 1; | 2441 | pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); |
2314 | pipe_info->err_count = 0; | 2442 | if (!pipe_info->stream_urb) { |
2315 | pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); | 2443 | dev_err(&dev->udev->dev, |
2316 | if (!pipe_info->stream_urb) { | 2444 | "ReadStream: Unable to alloc URB\n"); |
2317 | dev_err(&dev->udev->dev, | 2445 | return -ENOMEM; |
2318 | "ReadStream: Unable to alloc URB\n"); | 2446 | } |
2319 | return -ENOMEM; | 2447 | /* transfer buffer allocated in board_init */ |
2320 | } | 2448 | usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, |
2321 | /* transfer buffer allocated in board_init */ | 2449 | pipe, |
2322 | usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, | 2450 | pipe_info->transfer_buffer, |
2323 | pipe, | 2451 | pipe_info->cur_transfer_size, |
2324 | pipe_info->transfer_buffer, | 2452 | read_pipe_completion, pipe_info); |
2325 | pipe_info->cur_transfer_size, | 2453 | retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); |
2326 | read_pipe_completion, pipe_info); | 2454 | if (retval) { |
2327 | 2455 | printk(KERN_ERR "s2255: start read pipe failed\n"); | |
2328 | dprintk(4, "submitting URB %p\n", pipe_info->stream_urb); | 2456 | return retval; |
2329 | retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); | ||
2330 | if (retval) { | ||
2331 | printk(KERN_ERR "s2255: start read pipe failed\n"); | ||
2332 | return retval; | ||
2333 | } | ||
2334 | } | 2457 | } |
2335 | |||
2336 | return 0; | 2458 | return 0; |
2337 | } | 2459 | } |
2338 | 2460 | ||
@@ -2347,10 +2469,7 @@ static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn) | |||
2347 | dprintk(2, "start acquire failed, bad channel %lu\n", chn); | 2469 | dprintk(2, "start acquire failed, bad channel %lu\n", chn); |
2348 | return -1; | 2470 | return -1; |
2349 | } | 2471 | } |
2350 | |||
2351 | chn_rev = G_chnmap[chn]; | 2472 | chn_rev = G_chnmap[chn]; |
2352 | dprintk(1, "S2255: start acquire %lu \n", chn); | ||
2353 | |||
2354 | buffer = kzalloc(512, GFP_KERNEL); | 2473 | buffer = kzalloc(512, GFP_KERNEL); |
2355 | if (buffer == NULL) { | 2474 | if (buffer == NULL) { |
2356 | dev_err(&dev->udev->dev, "out of mem\n"); | 2475 | dev_err(&dev->udev->dev, "out of mem\n"); |
@@ -2366,9 +2485,9 @@ static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn) | |||
2366 | } | 2485 | } |
2367 | 2486 | ||
2368 | /* send the start command */ | 2487 | /* send the start command */ |
2369 | *(u32 *) buffer = IN_DATA_TOKEN; | 2488 | *(__le32 *) buffer = IN_DATA_TOKEN; |
2370 | *((u32 *) buffer + 1) = (u32) chn_rev; | 2489 | *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev); |
2371 | *((u32 *) buffer + 2) = (u32) CMD_START; | 2490 | *((__le32 *) buffer + 2) = CMD_START; |
2372 | res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); | 2491 | res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); |
2373 | if (res != 0) | 2492 | if (res != 0) |
2374 | dev_err(&dev->udev->dev, "CMD_START error\n"); | 2493 | dev_err(&dev->udev->dev, "CMD_START error\n"); |
@@ -2383,65 +2502,41 @@ static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn) | |||
2383 | unsigned char *buffer; | 2502 | unsigned char *buffer; |
2384 | int res; | 2503 | int res; |
2385 | unsigned long chn_rev; | 2504 | unsigned long chn_rev; |
2386 | |||
2387 | if (chn >= MAX_CHANNELS) { | 2505 | if (chn >= MAX_CHANNELS) { |
2388 | dprintk(2, "stop acquire failed, bad channel %lu\n", chn); | 2506 | dprintk(2, "stop acquire failed, bad channel %lu\n", chn); |
2389 | return -1; | 2507 | return -1; |
2390 | } | 2508 | } |
2391 | chn_rev = G_chnmap[chn]; | 2509 | chn_rev = G_chnmap[chn]; |
2392 | |||
2393 | buffer = kzalloc(512, GFP_KERNEL); | 2510 | buffer = kzalloc(512, GFP_KERNEL); |
2394 | if (buffer == NULL) { | 2511 | if (buffer == NULL) { |
2395 | dev_err(&dev->udev->dev, "out of mem\n"); | 2512 | dev_err(&dev->udev->dev, "out of mem\n"); |
2396 | return -ENOMEM; | 2513 | return -ENOMEM; |
2397 | } | 2514 | } |
2398 | |||
2399 | /* send the stop command */ | 2515 | /* send the stop command */ |
2400 | dprintk(4, "stop acquire %lu\n", chn); | 2516 | *(__le32 *) buffer = IN_DATA_TOKEN; |
2401 | *(u32 *) buffer = IN_DATA_TOKEN; | 2517 | *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev); |
2402 | *((u32 *) buffer + 1) = (u32) chn_rev; | 2518 | *((__le32 *) buffer + 2) = CMD_STOP; |
2403 | *((u32 *) buffer + 2) = CMD_STOP; | ||
2404 | res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); | 2519 | res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); |
2405 | |||
2406 | if (res != 0) | 2520 | if (res != 0) |
2407 | dev_err(&dev->udev->dev, "CMD_STOP error\n"); | 2521 | dev_err(&dev->udev->dev, "CMD_STOP error\n"); |
2408 | |||
2409 | dprintk(4, "stop acquire: releasing states \n"); | ||
2410 | |||
2411 | kfree(buffer); | 2522 | kfree(buffer); |
2412 | dev->b_acquire[chn] = 0; | 2523 | dev->b_acquire[chn] = 0; |
2413 | 2524 | dprintk(4, "%s: chn %lu, res %d\n", __func__, chn, res); | |
2414 | return res; | 2525 | return res; |
2415 | } | 2526 | } |
2416 | 2527 | ||
2417 | static void s2255_stop_readpipe(struct s2255_dev *dev) | 2528 | static void s2255_stop_readpipe(struct s2255_dev *dev) |
2418 | { | 2529 | { |
2419 | int j; | 2530 | struct s2255_pipeinfo *pipe = &dev->pipe; |
2420 | |||
2421 | if (dev == NULL) { | ||
2422 | s2255_dev_err(&dev->udev->dev, "invalid device\n"); | ||
2423 | return; | ||
2424 | } | ||
2425 | dprintk(4, "stop read pipe\n"); | ||
2426 | for (j = 0; j < MAX_PIPE_BUFFERS; j++) { | ||
2427 | struct s2255_pipeinfo *pipe_info = &dev->pipes[j]; | ||
2428 | if (pipe_info) { | ||
2429 | if (pipe_info->state == 0) | ||
2430 | continue; | ||
2431 | pipe_info->state = 0; | ||
2432 | } | ||
2433 | } | ||
2434 | 2531 | ||
2435 | for (j = 0; j < MAX_PIPE_BUFFERS; j++) { | 2532 | pipe->state = 0; |
2436 | struct s2255_pipeinfo *pipe_info = &dev->pipes[j]; | 2533 | if (pipe->stream_urb) { |
2437 | if (pipe_info->stream_urb) { | 2534 | /* cancel urb */ |
2438 | /* cancel urb */ | 2535 | usb_kill_urb(pipe->stream_urb); |
2439 | usb_kill_urb(pipe_info->stream_urb); | 2536 | usb_free_urb(pipe->stream_urb); |
2440 | usb_free_urb(pipe_info->stream_urb); | 2537 | pipe->stream_urb = NULL; |
2441 | pipe_info->stream_urb = NULL; | ||
2442 | } | ||
2443 | } | 2538 | } |
2444 | dprintk(2, "s2255 stop read pipe: %d\n", j); | 2539 | dprintk(4, "%s", __func__); |
2445 | return; | 2540 | return; |
2446 | } | 2541 | } |
2447 | 2542 | ||
@@ -2473,32 +2568,28 @@ static int s2255_probe(struct usb_interface *interface, | |||
2473 | int retval = -ENOMEM; | 2568 | int retval = -ENOMEM; |
2474 | __le32 *pdata; | 2569 | __le32 *pdata; |
2475 | int fw_size; | 2570 | int fw_size; |
2476 | 2571 | dprintk(2, "%s\n", __func__); | |
2477 | dprintk(2, "s2255: probe\n"); | ||
2478 | |||
2479 | /* allocate memory for our device state and initialize it to zero */ | 2572 | /* allocate memory for our device state and initialize it to zero */ |
2480 | dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL); | 2573 | dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL); |
2481 | if (dev == NULL) { | 2574 | if (dev == NULL) { |
2482 | s2255_dev_err(&interface->dev, "out of memory\n"); | 2575 | s2255_dev_err(&interface->dev, "out of memory\n"); |
2483 | goto error; | 2576 | return -ENOMEM; |
2484 | } | 2577 | } |
2485 | 2578 | atomic_set(&dev->channels, 0); | |
2579 | dev->pid = id->idProduct; | ||
2486 | dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL); | 2580 | dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL); |
2487 | if (!dev->fw_data) | 2581 | if (!dev->fw_data) |
2488 | goto error; | 2582 | goto errorFWDATA1; |
2489 | |||
2490 | mutex_init(&dev->lock); | 2583 | mutex_init(&dev->lock); |
2491 | mutex_init(&dev->open_lock); | 2584 | mutex_init(&dev->open_lock); |
2492 | |||
2493 | /* grab usb_device and save it */ | 2585 | /* grab usb_device and save it */ |
2494 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); | 2586 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); |
2495 | if (dev->udev == NULL) { | 2587 | if (dev->udev == NULL) { |
2496 | dev_err(&interface->dev, "null usb device\n"); | 2588 | dev_err(&interface->dev, "null usb device\n"); |
2497 | retval = -ENODEV; | 2589 | retval = -ENODEV; |
2498 | goto error; | 2590 | goto errorUDEV; |
2499 | } | 2591 | } |
2500 | kref_init(&dev->kref); | 2592 | dprintk(1, "dev: %p, udev %p interface %p\n", dev, |
2501 | dprintk(1, "dev: %p, kref: %p udev %p interface %p\n", dev, &dev->kref, | ||
2502 | dev->udev, interface); | 2593 | dev->udev, interface); |
2503 | dev->interface = interface; | 2594 | dev->interface = interface; |
2504 | /* set up the endpoint information */ | 2595 | /* set up the endpoint information */ |
@@ -2514,39 +2605,33 @@ static int s2255_probe(struct usb_interface *interface, | |||
2514 | 2605 | ||
2515 | if (!dev->read_endpoint) { | 2606 | if (!dev->read_endpoint) { |
2516 | dev_err(&interface->dev, "Could not find bulk-in endpoint\n"); | 2607 | dev_err(&interface->dev, "Could not find bulk-in endpoint\n"); |
2517 | goto error; | 2608 | goto errorEP; |
2518 | } | 2609 | } |
2519 | |||
2520 | /* set intfdata */ | ||
2521 | usb_set_intfdata(interface, dev); | ||
2522 | |||
2523 | dprintk(100, "after intfdata %p\n", dev); | ||
2524 | |||
2525 | init_timer(&dev->timer); | 2610 | init_timer(&dev->timer); |
2526 | dev->timer.function = s2255_timer; | 2611 | dev->timer.function = s2255_timer; |
2527 | dev->timer.data = (unsigned long)dev->fw_data; | 2612 | dev->timer.data = (unsigned long)dev->fw_data; |
2528 | |||
2529 | init_waitqueue_head(&dev->fw_data->wait_fw); | 2613 | init_waitqueue_head(&dev->fw_data->wait_fw); |
2530 | for (i = 0; i < MAX_CHANNELS; i++) | 2614 | for (i = 0; i < MAX_CHANNELS; i++) { |
2531 | init_waitqueue_head(&dev->wait_setmode[i]); | 2615 | init_waitqueue_head(&dev->wait_setmode[i]); |
2532 | 2616 | init_waitqueue_head(&dev->wait_vidstatus[i]); | |
2617 | } | ||
2533 | 2618 | ||
2534 | dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); | 2619 | dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); |
2535 | |||
2536 | if (!dev->fw_data->fw_urb) { | 2620 | if (!dev->fw_data->fw_urb) { |
2537 | dev_err(&interface->dev, "out of memory!\n"); | 2621 | dev_err(&interface->dev, "out of memory!\n"); |
2538 | goto error; | 2622 | goto errorFWURB; |
2539 | } | 2623 | } |
2624 | |||
2540 | dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL); | 2625 | dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL); |
2541 | if (!dev->fw_data->pfw_data) { | 2626 | if (!dev->fw_data->pfw_data) { |
2542 | dev_err(&interface->dev, "out of memory!\n"); | 2627 | dev_err(&interface->dev, "out of memory!\n"); |
2543 | goto error; | 2628 | goto errorFWDATA2; |
2544 | } | 2629 | } |
2545 | /* load the first chunk */ | 2630 | /* load the first chunk */ |
2546 | if (request_firmware(&dev->fw_data->fw, | 2631 | if (request_firmware(&dev->fw_data->fw, |
2547 | FIRMWARE_FILE_NAME, &dev->udev->dev)) { | 2632 | FIRMWARE_FILE_NAME, &dev->udev->dev)) { |
2548 | printk(KERN_ERR "sensoray 2255 failed to get firmware\n"); | 2633 | printk(KERN_ERR "sensoray 2255 failed to get firmware\n"); |
2549 | goto error; | 2634 | goto errorREQFW; |
2550 | } | 2635 | } |
2551 | /* check the firmware is valid */ | 2636 | /* check the firmware is valid */ |
2552 | fw_size = dev->fw_data->fw->size; | 2637 | fw_size = dev->fw_data->fw->size; |
@@ -2555,59 +2640,80 @@ static int s2255_probe(struct usb_interface *interface, | |||
2555 | if (*pdata != S2255_FW_MARKER) { | 2640 | if (*pdata != S2255_FW_MARKER) { |
2556 | printk(KERN_INFO "Firmware invalid.\n"); | 2641 | printk(KERN_INFO "Firmware invalid.\n"); |
2557 | retval = -ENODEV; | 2642 | retval = -ENODEV; |
2558 | goto error; | 2643 | goto errorFWMARKER; |
2559 | } else { | 2644 | } else { |
2560 | /* make sure firmware is the latest */ | 2645 | /* make sure firmware is the latest */ |
2561 | __le32 *pRel; | 2646 | __le32 *pRel; |
2562 | pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4]; | 2647 | pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4]; |
2563 | printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel); | 2648 | printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel); |
2649 | dev->dsp_fw_ver = *pRel; | ||
2650 | if (*pRel < S2255_CUR_DSP_FWVER) | ||
2651 | printk(KERN_INFO "s2255: f2255usb.bin out of date.\n"); | ||
2652 | if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER) | ||
2653 | printk(KERN_WARNING "s2255: 2257 requires firmware %d" | ||
2654 | "or above.\n", S2255_MIN_DSP_COLORFILTER); | ||
2564 | } | 2655 | } |
2565 | /* loads v4l specific */ | ||
2566 | s2255_probe_v4l(dev); | ||
2567 | usb_reset_device(dev->udev); | 2656 | usb_reset_device(dev->udev); |
2568 | /* load 2255 board specific */ | 2657 | /* load 2255 board specific */ |
2569 | retval = s2255_board_init(dev); | 2658 | retval = s2255_board_init(dev); |
2570 | if (retval) | 2659 | if (retval) |
2571 | goto error; | 2660 | goto errorBOARDINIT; |
2572 | |||
2573 | dprintk(4, "before probe done %p\n", dev); | ||
2574 | spin_lock_init(&dev->slock); | 2661 | spin_lock_init(&dev->slock); |
2575 | |||
2576 | s2255_fwload_start(dev, 0); | 2662 | s2255_fwload_start(dev, 0); |
2663 | /* loads v4l specific */ | ||
2664 | retval = s2255_probe_v4l(dev); | ||
2665 | if (retval) | ||
2666 | goto errorBOARDINIT; | ||
2577 | dev_info(&interface->dev, "Sensoray 2255 detected\n"); | 2667 | dev_info(&interface->dev, "Sensoray 2255 detected\n"); |
2578 | return 0; | 2668 | return 0; |
2579 | error: | 2669 | errorBOARDINIT: |
2670 | s2255_board_shutdown(dev); | ||
2671 | errorFWMARKER: | ||
2672 | release_firmware(dev->fw_data->fw); | ||
2673 | errorREQFW: | ||
2674 | kfree(dev->fw_data->pfw_data); | ||
2675 | errorFWDATA2: | ||
2676 | usb_free_urb(dev->fw_data->fw_urb); | ||
2677 | errorFWURB: | ||
2678 | del_timer(&dev->timer); | ||
2679 | errorEP: | ||
2680 | usb_put_dev(dev->udev); | ||
2681 | errorUDEV: | ||
2682 | kfree(dev->fw_data); | ||
2683 | mutex_destroy(&dev->open_lock); | ||
2684 | mutex_destroy(&dev->lock); | ||
2685 | errorFWDATA1: | ||
2686 | kfree(dev); | ||
2687 | printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval); | ||
2580 | return retval; | 2688 | return retval; |
2581 | } | 2689 | } |
2582 | 2690 | ||
2583 | /* disconnect routine. when board is removed physically or with rmmod */ | 2691 | /* disconnect routine. when board is removed physically or with rmmod */ |
2584 | static void s2255_disconnect(struct usb_interface *interface) | 2692 | static void s2255_disconnect(struct usb_interface *interface) |
2585 | { | 2693 | { |
2586 | struct s2255_dev *dev = NULL; | 2694 | struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface)); |
2587 | int i; | 2695 | int i; |
2588 | dprintk(1, "s2255: disconnect interface %p\n", interface); | 2696 | int channels = atomic_read(&dev->channels); |
2589 | dev = usb_get_intfdata(interface); | 2697 | v4l2_device_unregister(&dev->v4l2_dev); |
2590 | 2698 | /*see comments in the uvc_driver.c usb disconnect function */ | |
2591 | /* | 2699 | atomic_inc(&dev->channels); |
2592 | * wake up any of the timers to allow open_lock to be | 2700 | /* unregister each video device. */ |
2593 | * acquired sooner | 2701 | for (i = 0; i < channels; i++) { |
2594 | */ | 2702 | if (video_is_registered(&dev->vdev[i])) |
2703 | video_unregister_device(&dev->vdev[i]); | ||
2704 | } | ||
2705 | /* wake up any of our timers */ | ||
2595 | atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); | 2706 | atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); |
2596 | wake_up(&dev->fw_data->wait_fw); | 2707 | wake_up(&dev->fw_data->wait_fw); |
2597 | for (i = 0; i < MAX_CHANNELS; i++) { | 2708 | for (i = 0; i < MAX_CHANNELS; i++) { |
2598 | dev->setmode_ready[i] = 1; | 2709 | dev->setmode_ready[i] = 1; |
2599 | wake_up(&dev->wait_setmode[i]); | 2710 | wake_up(&dev->wait_setmode[i]); |
2711 | dev->vidstatus_ready[i] = 1; | ||
2712 | wake_up(&dev->wait_vidstatus[i]); | ||
2600 | } | 2713 | } |
2601 | 2714 | if (atomic_dec_and_test(&dev->channels)) | |
2602 | mutex_lock(&dev->open_lock); | 2715 | s2255_destroy(dev); |
2603 | usb_set_intfdata(interface, NULL); | 2716 | dev_info(&interface->dev, "%s\n", __func__); |
2604 | mutex_unlock(&dev->open_lock); | ||
2605 | |||
2606 | if (dev) { | ||
2607 | kref_put(&dev->kref, s2255_destroy); | ||
2608 | dprintk(1, "s2255drv: disconnect\n"); | ||
2609 | dev_info(&interface->dev, "s2255usb now disconnected\n"); | ||
2610 | } | ||
2611 | } | 2717 | } |
2612 | 2718 | ||
2613 | static struct usb_driver s2255_driver = { | 2719 | static struct usb_driver s2255_driver = { |
@@ -2620,15 +2726,12 @@ static struct usb_driver s2255_driver = { | |||
2620 | static int __init usb_s2255_init(void) | 2726 | static int __init usb_s2255_init(void) |
2621 | { | 2727 | { |
2622 | int result; | 2728 | int result; |
2623 | |||
2624 | /* register this driver with the USB subsystem */ | 2729 | /* register this driver with the USB subsystem */ |
2625 | result = usb_register(&s2255_driver); | 2730 | result = usb_register(&s2255_driver); |
2626 | |||
2627 | if (result) | 2731 | if (result) |
2628 | pr_err(KBUILD_MODNAME | 2732 | pr_err(KBUILD_MODNAME |
2629 | ": usb_register failed. Error number %d\n", result); | 2733 | ": usb_register failed. Error number %d\n", result); |
2630 | 2734 | dprintk(2, "%s\n", __func__); | |
2631 | dprintk(2, "s2255_init: done\n"); | ||
2632 | return result; | 2735 | return result; |
2633 | } | 2736 | } |
2634 | 2737 | ||