diff options
Diffstat (limited to 'drivers/media/usb/usbtv/usbtv.c')
-rw-r--r-- | drivers/media/usb/usbtv/usbtv.c | 174 |
1 files changed, 136 insertions, 38 deletions
diff --git a/drivers/media/usb/usbtv/usbtv.c b/drivers/media/usb/usbtv/usbtv.c index 8a505a90d318..6222a4ab1e00 100644 --- a/drivers/media/usb/usbtv/usbtv.c +++ b/drivers/media/usb/usbtv/usbtv.c | |||
@@ -50,13 +50,8 @@ | |||
50 | #define USBTV_ISOC_TRANSFERS 16 | 50 | #define USBTV_ISOC_TRANSFERS 16 |
51 | #define USBTV_ISOC_PACKETS 8 | 51 | #define USBTV_ISOC_PACKETS 8 |
52 | 52 | ||
53 | #define USBTV_WIDTH 720 | ||
54 | #define USBTV_HEIGHT 480 | ||
55 | |||
56 | #define USBTV_CHUNK_SIZE 256 | 53 | #define USBTV_CHUNK_SIZE 256 |
57 | #define USBTV_CHUNK 240 | 54 | #define USBTV_CHUNK 240 |
58 | #define USBTV_CHUNKS (USBTV_WIDTH * USBTV_HEIGHT \ | ||
59 | / 4 / USBTV_CHUNK) | ||
60 | 55 | ||
61 | /* Chunk header. */ | 56 | /* Chunk header. */ |
62 | #define USBTV_MAGIC_OK(chunk) ((be32_to_cpu(chunk[0]) & 0xff000000) \ | 57 | #define USBTV_MAGIC_OK(chunk) ((be32_to_cpu(chunk[0]) & 0xff000000) \ |
@@ -65,6 +60,27 @@ | |||
65 | #define USBTV_ODD(chunk) ((be32_to_cpu(chunk[0]) & 0x0000f000) >> 15) | 60 | #define USBTV_ODD(chunk) ((be32_to_cpu(chunk[0]) & 0x0000f000) >> 15) |
66 | #define USBTV_CHUNK_NO(chunk) (be32_to_cpu(chunk[0]) & 0x00000fff) | 61 | #define USBTV_CHUNK_NO(chunk) (be32_to_cpu(chunk[0]) & 0x00000fff) |
67 | 62 | ||
63 | #define USBTV_TV_STD (V4L2_STD_525_60 | V4L2_STD_PAL) | ||
64 | |||
65 | /* parameters for supported TV norms */ | ||
66 | struct usbtv_norm_params { | ||
67 | v4l2_std_id norm; | ||
68 | int cap_width, cap_height; | ||
69 | }; | ||
70 | |||
71 | static struct usbtv_norm_params norm_params[] = { | ||
72 | { | ||
73 | .norm = V4L2_STD_525_60, | ||
74 | .cap_width = 720, | ||
75 | .cap_height = 480, | ||
76 | }, | ||
77 | { | ||
78 | .norm = V4L2_STD_PAL, | ||
79 | .cap_width = 720, | ||
80 | .cap_height = 576, | ||
81 | } | ||
82 | }; | ||
83 | |||
68 | /* A single videobuf2 frame buffer. */ | 84 | /* A single videobuf2 frame buffer. */ |
69 | struct usbtv_buf { | 85 | struct usbtv_buf { |
70 | struct vb2_buffer vb; | 86 | struct vb2_buffer vb; |
@@ -94,11 +110,38 @@ struct usbtv { | |||
94 | USBTV_COMPOSITE_INPUT, | 110 | USBTV_COMPOSITE_INPUT, |
95 | USBTV_SVIDEO_INPUT, | 111 | USBTV_SVIDEO_INPUT, |
96 | } input; | 112 | } input; |
113 | v4l2_std_id norm; | ||
114 | int width, height; | ||
115 | int n_chunks; | ||
97 | int iso_size; | 116 | int iso_size; |
98 | unsigned int sequence; | 117 | unsigned int sequence; |
99 | struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS]; | 118 | struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS]; |
100 | }; | 119 | }; |
101 | 120 | ||
121 | static int usbtv_configure_for_norm(struct usbtv *usbtv, v4l2_std_id norm) | ||
122 | { | ||
123 | int i, ret = 0; | ||
124 | struct usbtv_norm_params *params = NULL; | ||
125 | |||
126 | for (i = 0; i < ARRAY_SIZE(norm_params); i++) { | ||
127 | if (norm_params[i].norm & norm) { | ||
128 | params = &norm_params[i]; | ||
129 | break; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | if (params) { | ||
134 | usbtv->width = params->cap_width; | ||
135 | usbtv->height = params->cap_height; | ||
136 | usbtv->n_chunks = usbtv->width * usbtv->height | ||
137 | / 4 / USBTV_CHUNK; | ||
138 | usbtv->norm = params->norm; | ||
139 | } else | ||
140 | ret = -EINVAL; | ||
141 | |||
142 | return ret; | ||
143 | } | ||
144 | |||
102 | static int usbtv_set_regs(struct usbtv *usbtv, const u16 regs[][2], int size) | 145 | static int usbtv_set_regs(struct usbtv *usbtv, const u16 regs[][2], int size) |
103 | { | 146 | { |
104 | int ret; | 147 | int ret; |
@@ -158,6 +201,57 @@ static int usbtv_select_input(struct usbtv *usbtv, int input) | |||
158 | return ret; | 201 | return ret; |
159 | } | 202 | } |
160 | 203 | ||
204 | static int usbtv_select_norm(struct usbtv *usbtv, v4l2_std_id norm) | ||
205 | { | ||
206 | int ret; | ||
207 | static const u16 pal[][2] = { | ||
208 | { USBTV_BASE + 0x001a, 0x0068 }, | ||
209 | { USBTV_BASE + 0x010e, 0x0072 }, | ||
210 | { USBTV_BASE + 0x010f, 0x00a2 }, | ||
211 | { USBTV_BASE + 0x0112, 0x00b0 }, | ||
212 | { USBTV_BASE + 0x0117, 0x0001 }, | ||
213 | { USBTV_BASE + 0x0118, 0x002c }, | ||
214 | { USBTV_BASE + 0x012d, 0x0010 }, | ||
215 | { USBTV_BASE + 0x012f, 0x0020 }, | ||
216 | { USBTV_BASE + 0x024f, 0x0002 }, | ||
217 | { USBTV_BASE + 0x0254, 0x0059 }, | ||
218 | { USBTV_BASE + 0x025a, 0x0016 }, | ||
219 | { USBTV_BASE + 0x025b, 0x0035 }, | ||
220 | { USBTV_BASE + 0x0263, 0x0017 }, | ||
221 | { USBTV_BASE + 0x0266, 0x0016 }, | ||
222 | { USBTV_BASE + 0x0267, 0x0036 } | ||
223 | }; | ||
224 | |||
225 | static const u16 ntsc[][2] = { | ||
226 | { USBTV_BASE + 0x001a, 0x0079 }, | ||
227 | { USBTV_BASE + 0x010e, 0x0068 }, | ||
228 | { USBTV_BASE + 0x010f, 0x009c }, | ||
229 | { USBTV_BASE + 0x0112, 0x00f0 }, | ||
230 | { USBTV_BASE + 0x0117, 0x0000 }, | ||
231 | { USBTV_BASE + 0x0118, 0x00fc }, | ||
232 | { USBTV_BASE + 0x012d, 0x0004 }, | ||
233 | { USBTV_BASE + 0x012f, 0x0008 }, | ||
234 | { USBTV_BASE + 0x024f, 0x0001 }, | ||
235 | { USBTV_BASE + 0x0254, 0x005f }, | ||
236 | { USBTV_BASE + 0x025a, 0x0012 }, | ||
237 | { USBTV_BASE + 0x025b, 0x0001 }, | ||
238 | { USBTV_BASE + 0x0263, 0x001c }, | ||
239 | { USBTV_BASE + 0x0266, 0x0011 }, | ||
240 | { USBTV_BASE + 0x0267, 0x0005 } | ||
241 | }; | ||
242 | |||
243 | ret = usbtv_configure_for_norm(usbtv, norm); | ||
244 | |||
245 | if (!ret) { | ||
246 | if (norm & V4L2_STD_525_60) | ||
247 | ret = usbtv_set_regs(usbtv, ntsc, ARRAY_SIZE(ntsc)); | ||
248 | else if (norm & V4L2_STD_PAL) | ||
249 | ret = usbtv_set_regs(usbtv, pal, ARRAY_SIZE(pal)); | ||
250 | } | ||
251 | |||
252 | return ret; | ||
253 | } | ||
254 | |||
161 | static int usbtv_setup_capture(struct usbtv *usbtv) | 255 | static int usbtv_setup_capture(struct usbtv *usbtv) |
162 | { | 256 | { |
163 | int ret; | 257 | int ret; |
@@ -225,26 +319,11 @@ static int usbtv_setup_capture(struct usbtv *usbtv) | |||
225 | 319 | ||
226 | { USBTV_BASE + 0x0284, 0x0088 }, | 320 | { USBTV_BASE + 0x0284, 0x0088 }, |
227 | { USBTV_BASE + 0x0003, 0x0004 }, | 321 | { USBTV_BASE + 0x0003, 0x0004 }, |
228 | { USBTV_BASE + 0x001a, 0x0079 }, | ||
229 | { USBTV_BASE + 0x0100, 0x00d3 }, | 322 | { USBTV_BASE + 0x0100, 0x00d3 }, |
230 | { USBTV_BASE + 0x010e, 0x0068 }, | ||
231 | { USBTV_BASE + 0x010f, 0x009c }, | ||
232 | { USBTV_BASE + 0x0112, 0x00f0 }, | ||
233 | { USBTV_BASE + 0x0115, 0x0015 }, | 323 | { USBTV_BASE + 0x0115, 0x0015 }, |
234 | { USBTV_BASE + 0x0117, 0x0000 }, | ||
235 | { USBTV_BASE + 0x0118, 0x00fc }, | ||
236 | { USBTV_BASE + 0x012d, 0x0004 }, | ||
237 | { USBTV_BASE + 0x012f, 0x0008 }, | ||
238 | { USBTV_BASE + 0x0220, 0x002e }, | 324 | { USBTV_BASE + 0x0220, 0x002e }, |
239 | { USBTV_BASE + 0x0225, 0x0008 }, | 325 | { USBTV_BASE + 0x0225, 0x0008 }, |
240 | { USBTV_BASE + 0x024e, 0x0002 }, | 326 | { USBTV_BASE + 0x024e, 0x0002 }, |
241 | { USBTV_BASE + 0x024f, 0x0001 }, | ||
242 | { USBTV_BASE + 0x0254, 0x005f }, | ||
243 | { USBTV_BASE + 0x025a, 0x0012 }, | ||
244 | { USBTV_BASE + 0x025b, 0x0001 }, | ||
245 | { USBTV_BASE + 0x0263, 0x001c }, | ||
246 | { USBTV_BASE + 0x0266, 0x0011 }, | ||
247 | { USBTV_BASE + 0x0267, 0x0005 }, | ||
248 | { USBTV_BASE + 0x024e, 0x0002 }, | 327 | { USBTV_BASE + 0x024e, 0x0002 }, |
249 | { USBTV_BASE + 0x024f, 0x0002 }, | 328 | { USBTV_BASE + 0x024f, 0x0002 }, |
250 | }; | 329 | }; |
@@ -253,6 +332,10 @@ static int usbtv_setup_capture(struct usbtv *usbtv) | |||
253 | if (ret) | 332 | if (ret) |
254 | return ret; | 333 | return ret; |
255 | 334 | ||
335 | ret = usbtv_select_norm(usbtv, usbtv->norm); | ||
336 | if (ret) | ||
337 | return ret; | ||
338 | |||
256 | ret = usbtv_select_input(usbtv, usbtv->input); | 339 | ret = usbtv_select_input(usbtv, usbtv->input); |
257 | if (ret) | 340 | if (ret) |
258 | return ret; | 341 | return ret; |
@@ -296,7 +379,7 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk) | |||
296 | frame_id = USBTV_FRAME_ID(chunk); | 379 | frame_id = USBTV_FRAME_ID(chunk); |
297 | odd = USBTV_ODD(chunk); | 380 | odd = USBTV_ODD(chunk); |
298 | chunk_no = USBTV_CHUNK_NO(chunk); | 381 | chunk_no = USBTV_CHUNK_NO(chunk); |
299 | if (chunk_no >= USBTV_CHUNKS) | 382 | if (chunk_no >= usbtv->n_chunks) |
300 | return; | 383 | return; |
301 | 384 | ||
302 | /* Beginning of a frame. */ | 385 | /* Beginning of a frame. */ |
@@ -324,10 +407,10 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk) | |||
324 | usbtv->chunks_done++; | 407 | usbtv->chunks_done++; |
325 | 408 | ||
326 | /* Last chunk in a frame, signalling an end */ | 409 | /* Last chunk in a frame, signalling an end */ |
327 | if (odd && chunk_no == USBTV_CHUNKS-1) { | 410 | if (odd && chunk_no == usbtv->n_chunks-1) { |
328 | int size = vb2_plane_size(&buf->vb, 0); | 411 | int size = vb2_plane_size(&buf->vb, 0); |
329 | enum vb2_buffer_state state = usbtv->chunks_done == | 412 | enum vb2_buffer_state state = usbtv->chunks_done == |
330 | USBTV_CHUNKS ? | 413 | usbtv->n_chunks ? |
331 | VB2_BUF_STATE_DONE : | 414 | VB2_BUF_STATE_DONE : |
332 | VB2_BUF_STATE_ERROR; | 415 | VB2_BUF_STATE_ERROR; |
333 | 416 | ||
@@ -500,6 +583,8 @@ static int usbtv_querycap(struct file *file, void *priv, | |||
500 | static int usbtv_enum_input(struct file *file, void *priv, | 583 | static int usbtv_enum_input(struct file *file, void *priv, |
501 | struct v4l2_input *i) | 584 | struct v4l2_input *i) |
502 | { | 585 | { |
586 | struct usbtv *dev = video_drvdata(file); | ||
587 | |||
503 | switch (i->index) { | 588 | switch (i->index) { |
504 | case USBTV_COMPOSITE_INPUT: | 589 | case USBTV_COMPOSITE_INPUT: |
505 | strlcpy(i->name, "Composite", sizeof(i->name)); | 590 | strlcpy(i->name, "Composite", sizeof(i->name)); |
@@ -512,7 +597,7 @@ static int usbtv_enum_input(struct file *file, void *priv, | |||
512 | } | 597 | } |
513 | 598 | ||
514 | i->type = V4L2_INPUT_TYPE_CAMERA; | 599 | i->type = V4L2_INPUT_TYPE_CAMERA; |
515 | i->std = V4L2_STD_525_60; | 600 | i->std = dev->vdev.tvnorms; |
516 | return 0; | 601 | return 0; |
517 | } | 602 | } |
518 | 603 | ||
@@ -531,23 +616,37 @@ static int usbtv_enum_fmt_vid_cap(struct file *file, void *priv, | |||
531 | static int usbtv_fmt_vid_cap(struct file *file, void *priv, | 616 | static int usbtv_fmt_vid_cap(struct file *file, void *priv, |
532 | struct v4l2_format *f) | 617 | struct v4l2_format *f) |
533 | { | 618 | { |
534 | f->fmt.pix.width = USBTV_WIDTH; | 619 | struct usbtv *usbtv = video_drvdata(file); |
535 | f->fmt.pix.height = USBTV_HEIGHT; | 620 | |
621 | f->fmt.pix.width = usbtv->width; | ||
622 | f->fmt.pix.height = usbtv->height; | ||
536 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | 623 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; |
537 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; | 624 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; |
538 | f->fmt.pix.bytesperline = USBTV_WIDTH * 2; | 625 | f->fmt.pix.bytesperline = usbtv->width * 2; |
539 | f->fmt.pix.sizeimage = (f->fmt.pix.bytesperline * f->fmt.pix.height); | 626 | f->fmt.pix.sizeimage = (f->fmt.pix.bytesperline * f->fmt.pix.height); |
540 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 627 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
541 | f->fmt.pix.priv = 0; | 628 | |
542 | return 0; | 629 | return 0; |
543 | } | 630 | } |
544 | 631 | ||
545 | static int usbtv_g_std(struct file *file, void *priv, v4l2_std_id *norm) | 632 | static int usbtv_g_std(struct file *file, void *priv, v4l2_std_id *norm) |
546 | { | 633 | { |
547 | *norm = V4L2_STD_525_60; | 634 | struct usbtv *usbtv = video_drvdata(file); |
635 | *norm = usbtv->norm; | ||
548 | return 0; | 636 | return 0; |
549 | } | 637 | } |
550 | 638 | ||
639 | static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm) | ||
640 | { | ||
641 | int ret = -EINVAL; | ||
642 | struct usbtv *usbtv = video_drvdata(file); | ||
643 | |||
644 | if ((norm & V4L2_STD_525_60) || (norm & V4L2_STD_PAL)) | ||
645 | ret = usbtv_select_norm(usbtv, norm); | ||
646 | |||
647 | return ret; | ||
648 | } | ||
649 | |||
551 | static int usbtv_g_input(struct file *file, void *priv, unsigned int *i) | 650 | static int usbtv_g_input(struct file *file, void *priv, unsigned int *i) |
552 | { | 651 | { |
553 | struct usbtv *usbtv = video_drvdata(file); | 652 | struct usbtv *usbtv = video_drvdata(file); |
@@ -561,13 +660,6 @@ static int usbtv_s_input(struct file *file, void *priv, unsigned int i) | |||
561 | return usbtv_select_input(usbtv, i); | 660 | return usbtv_select_input(usbtv, i); |
562 | } | 661 | } |
563 | 662 | ||
564 | static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm) | ||
565 | { | ||
566 | if (norm & V4L2_STD_525_60) | ||
567 | return 0; | ||
568 | return -EINVAL; | ||
569 | } | ||
570 | |||
571 | struct v4l2_ioctl_ops usbtv_ioctl_ops = { | 663 | struct v4l2_ioctl_ops usbtv_ioctl_ops = { |
572 | .vidioc_querycap = usbtv_querycap, | 664 | .vidioc_querycap = usbtv_querycap, |
573 | .vidioc_enum_input = usbtv_enum_input, | 665 | .vidioc_enum_input = usbtv_enum_input, |
@@ -604,10 +696,12 @@ static int usbtv_queue_setup(struct vb2_queue *vq, | |||
604 | const struct v4l2_format *v4l_fmt, unsigned int *nbuffers, | 696 | const struct v4l2_format *v4l_fmt, unsigned int *nbuffers, |
605 | unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) | 697 | unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) |
606 | { | 698 | { |
699 | struct usbtv *usbtv = vb2_get_drv_priv(vq); | ||
700 | |||
607 | if (*nbuffers < 2) | 701 | if (*nbuffers < 2) |
608 | *nbuffers = 2; | 702 | *nbuffers = 2; |
609 | *nplanes = 1; | 703 | *nplanes = 1; |
610 | sizes[0] = USBTV_WIDTH * USBTV_HEIGHT / 2 * sizeof(u32); | 704 | sizes[0] = USBTV_CHUNK * usbtv->n_chunks * 2 * sizeof(u32); |
611 | 705 | ||
612 | return 0; | 706 | return 0; |
613 | } | 707 | } |
@@ -690,7 +784,11 @@ static int usbtv_probe(struct usb_interface *intf, | |||
690 | return -ENOMEM; | 784 | return -ENOMEM; |
691 | usbtv->dev = dev; | 785 | usbtv->dev = dev; |
692 | usbtv->udev = usb_get_dev(interface_to_usbdev(intf)); | 786 | usbtv->udev = usb_get_dev(interface_to_usbdev(intf)); |
787 | |||
693 | usbtv->iso_size = size; | 788 | usbtv->iso_size = size; |
789 | |||
790 | (void)usbtv_configure_for_norm(usbtv, V4L2_STD_525_60); | ||
791 | |||
694 | spin_lock_init(&usbtv->buflock); | 792 | spin_lock_init(&usbtv->buflock); |
695 | mutex_init(&usbtv->v4l2_lock); | 793 | mutex_init(&usbtv->v4l2_lock); |
696 | mutex_init(&usbtv->vb2q_lock); | 794 | mutex_init(&usbtv->vb2q_lock); |
@@ -727,7 +825,7 @@ static int usbtv_probe(struct usb_interface *intf, | |||
727 | usbtv->vdev.release = video_device_release_empty; | 825 | usbtv->vdev.release = video_device_release_empty; |
728 | usbtv->vdev.fops = &usbtv_fops; | 826 | usbtv->vdev.fops = &usbtv_fops; |
729 | usbtv->vdev.ioctl_ops = &usbtv_ioctl_ops; | 827 | usbtv->vdev.ioctl_ops = &usbtv_ioctl_ops; |
730 | usbtv->vdev.tvnorms = V4L2_STD_525_60; | 828 | usbtv->vdev.tvnorms = USBTV_TV_STD; |
731 | usbtv->vdev.queue = &usbtv->vb2q; | 829 | usbtv->vdev.queue = &usbtv->vb2q; |
732 | usbtv->vdev.lock = &usbtv->v4l2_lock; | 830 | usbtv->vdev.lock = &usbtv->v4l2_lock; |
733 | set_bit(V4L2_FL_USE_FH_PRIO, &usbtv->vdev.flags); | 831 | set_bit(V4L2_FL_USE_FH_PRIO, &usbtv->vdev.flags); |