]>
Commit | Line | Data |
---|---|---|
7f8eacd2 DH |
1 | /* |
2 | au0828-vbi.c - VBI driver for au0828 | |
3 | ||
4 | Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com> | |
5 | ||
6 | This work was sponsored by GetWellNetwork Inc. | |
7 | ||
8 | This program is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 2 of the License, or | |
11 | (at your option) any later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with this program; if not, write to the Free Software | |
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
21 | 02110-1301, USA. | |
22 | */ | |
23 | ||
83afb32a MCC |
24 | #include "au0828.h" |
25 | ||
7f8eacd2 DH |
26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | |
28 | #include <linux/init.h> | |
29 | #include <linux/slab.h> | |
30 | ||
7f8eacd2 DH |
31 | /* ------------------------------------------------------------------ */ |
32 | ||
05439b1a SK |
33 | static int vbi_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, |
34 | unsigned int *nbuffers, unsigned int *nplanes, | |
35 | unsigned int sizes[], void *alloc_ctxs[]) | |
7f8eacd2 | 36 | { |
05439b1a SK |
37 | struct au0828_dev *dev = vb2_get_drv_priv(vq); |
38 | unsigned long img_size = dev->vbi_width * dev->vbi_height * 2; | |
39 | unsigned long size; | |
7f8eacd2 | 40 | |
05439b1a SK |
41 | size = fmt ? (fmt->fmt.vbi.samples_per_line * |
42 | (fmt->fmt.vbi.count[0] + fmt->fmt.vbi.count[1])) : img_size; | |
43 | if (size < img_size) | |
44 | return -EINVAL; | |
7f8eacd2 | 45 | |
05439b1a SK |
46 | *nplanes = 1; |
47 | sizes[0] = size; | |
7f8eacd2 | 48 | |
7f8eacd2 DH |
49 | return 0; |
50 | } | |
51 | ||
05439b1a | 52 | static int vbi_buffer_prepare(struct vb2_buffer *vb) |
7f8eacd2 | 53 | { |
05439b1a | 54 | struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue); |
05439b1a | 55 | unsigned long size; |
7f8eacd2 | 56 | |
05439b1a | 57 | size = dev->vbi_width * dev->vbi_height * 2; |
7f8eacd2 | 58 | |
05439b1a SK |
59 | if (vb2_plane_size(vb, 0) < size) { |
60 | pr_err("%s data will not fit into plane (%lu < %lu)\n", | |
61 | __func__, vb2_plane_size(vb, 0), size); | |
7f8eacd2 | 62 | return -EINVAL; |
7f8eacd2 | 63 | } |
2d700715 | 64 | vb2_set_plane_payload(vb, 0, size); |
7f8eacd2 | 65 | |
7f8eacd2 | 66 | return 0; |
7f8eacd2 DH |
67 | } |
68 | ||
69 | static void | |
05439b1a | 70 | vbi_buffer_queue(struct vb2_buffer *vb) |
7f8eacd2 | 71 | { |
05439b1a | 72 | struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue); |
2d700715 JS |
73 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
74 | struct au0828_buffer *buf = | |
75 | container_of(vbuf, struct au0828_buffer, vb); | |
05439b1a SK |
76 | struct au0828_dmaqueue *vbiq = &dev->vbiq; |
77 | unsigned long flags = 0; | |
78 | ||
79 | buf->mem = vb2_plane_vaddr(vb, 0); | |
80 | buf->length = vb2_plane_size(vb, 0); | |
81 | ||
82 | spin_lock_irqsave(&dev->slock, flags); | |
83 | list_add_tail(&buf->list, &vbiq->active); | |
84 | spin_unlock_irqrestore(&dev->slock, flags); | |
7f8eacd2 DH |
85 | } |
86 | ||
05439b1a SK |
87 | struct vb2_ops au0828_vbi_qops = { |
88 | .queue_setup = vbi_queue_setup, | |
89 | .buf_prepare = vbi_buffer_prepare, | |
90 | .buf_queue = vbi_buffer_queue, | |
91 | .start_streaming = au0828_start_analog_streaming, | |
92 | .stop_streaming = au0828_stop_vbi_streaming, | |
93 | .wait_prepare = vb2_ops_wait_prepare, | |
94 | .wait_finish = vb2_ops_wait_finish, | |
7f8eacd2 | 95 | }; |