diff options
Diffstat (limited to 'drivers/media/video/bttv-vbi.c')
-rw-r--r-- | drivers/media/video/bttv-vbi.c | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c new file mode 100644 index 000000000000..06f3e62b3e8d --- /dev/null +++ b/drivers/media/video/bttv-vbi.c | |||
@@ -0,0 +1,235 @@ | |||
1 | /* | ||
2 | $Id: bttv-vbi.c,v 1.9 2005/01/13 17:22:33 kraxel Exp $ | ||
3 | |||
4 | bttv - Bt848 frame grabber driver | ||
5 | vbi interface | ||
6 | |||
7 | (c) 2002 Gerd Knorr <kraxel@bytesex.org> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/moduleparam.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/fs.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/interrupt.h> | ||
31 | #include <linux/kdev_t.h> | ||
32 | #include <asm/io.h> | ||
33 | #include "bttvp.h" | ||
34 | |||
35 | #define VBI_DEFLINES 16 | ||
36 | #define VBI_MAXLINES 32 | ||
37 | |||
38 | static unsigned int vbibufs = 4; | ||
39 | static unsigned int vbi_debug = 0; | ||
40 | |||
41 | module_param(vbibufs, int, 0444); | ||
42 | module_param(vbi_debug, int, 0644); | ||
43 | MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32, default 4"); | ||
44 | MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)"); | ||
45 | |||
46 | #ifdef dprintk | ||
47 | # undef dprintk | ||
48 | #endif | ||
49 | #define dprintk(fmt, arg...) if (vbi_debug) \ | ||
50 | printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg) | ||
51 | |||
52 | /* ----------------------------------------------------------------------- */ | ||
53 | /* vbi risc code + mm */ | ||
54 | |||
55 | static int | ||
56 | vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines) | ||
57 | { | ||
58 | int bpl = 2048; | ||
59 | |||
60 | bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist, | ||
61 | 0, bpl-4, 4, lines); | ||
62 | bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist, | ||
63 | lines * bpl, bpl-4, 4, lines); | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static int vbi_buffer_setup(struct videobuf_queue *q, | ||
68 | unsigned int *count, unsigned int *size) | ||
69 | { | ||
70 | struct bttv_fh *fh = q->priv_data; | ||
71 | struct bttv *btv = fh->btv; | ||
72 | |||
73 | if (0 == *count) | ||
74 | *count = vbibufs; | ||
75 | *size = fh->lines * 2 * 2048; | ||
76 | dprintk("setup: lines=%d\n",fh->lines); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int vbi_buffer_prepare(struct videobuf_queue *q, | ||
81 | struct videobuf_buffer *vb, | ||
82 | enum v4l2_field field) | ||
83 | { | ||
84 | struct bttv_fh *fh = q->priv_data; | ||
85 | struct bttv *btv = fh->btv; | ||
86 | struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); | ||
87 | int rc; | ||
88 | |||
89 | buf->vb.size = fh->lines * 2 * 2048; | ||
90 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | ||
91 | return -EINVAL; | ||
92 | |||
93 | if (STATE_NEEDS_INIT == buf->vb.state) { | ||
94 | if (0 != (rc = videobuf_iolock(btv->c.pci, &buf->vb, NULL))) | ||
95 | goto fail; | ||
96 | if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines))) | ||
97 | goto fail; | ||
98 | } | ||
99 | buf->vb.state = STATE_PREPARED; | ||
100 | buf->vb.field = field; | ||
101 | dprintk("buf prepare %p: top=%p bottom=%p field=%s\n", | ||
102 | vb, &buf->top, &buf->bottom, | ||
103 | v4l2_field_names[buf->vb.field]); | ||
104 | return 0; | ||
105 | |||
106 | fail: | ||
107 | bttv_dma_free(btv,buf); | ||
108 | return rc; | ||
109 | } | ||
110 | |||
111 | static void | ||
112 | vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | ||
113 | { | ||
114 | struct bttv_fh *fh = q->priv_data; | ||
115 | struct bttv *btv = fh->btv; | ||
116 | struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); | ||
117 | |||
118 | dprintk("queue %p\n",vb); | ||
119 | buf->vb.state = STATE_QUEUED; | ||
120 | list_add_tail(&buf->vb.queue,&btv->vcapture); | ||
121 | if (NULL == btv->cvbi) { | ||
122 | fh->btv->loop_irq |= 4; | ||
123 | bttv_set_dma(btv,0x0c); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | ||
128 | { | ||
129 | struct bttv_fh *fh = q->priv_data; | ||
130 | struct bttv *btv = fh->btv; | ||
131 | struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); | ||
132 | |||
133 | dprintk("free %p\n",vb); | ||
134 | bttv_dma_free(fh->btv,buf); | ||
135 | } | ||
136 | |||
137 | struct videobuf_queue_ops bttv_vbi_qops = { | ||
138 | .buf_setup = vbi_buffer_setup, | ||
139 | .buf_prepare = vbi_buffer_prepare, | ||
140 | .buf_queue = vbi_buffer_queue, | ||
141 | .buf_release = vbi_buffer_release, | ||
142 | }; | ||
143 | |||
144 | /* ----------------------------------------------------------------------- */ | ||
145 | |||
146 | void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines) | ||
147 | { | ||
148 | int vdelay; | ||
149 | |||
150 | if (lines < 1) | ||
151 | lines = 1; | ||
152 | if (lines > VBI_MAXLINES) | ||
153 | lines = VBI_MAXLINES; | ||
154 | fh->lines = lines; | ||
155 | |||
156 | vdelay = btread(BT848_E_VDELAY_LO); | ||
157 | if (vdelay < lines*2) { | ||
158 | vdelay = lines*2; | ||
159 | btwrite(vdelay,BT848_E_VDELAY_LO); | ||
160 | btwrite(vdelay,BT848_O_VDELAY_LO); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f) | ||
165 | { | ||
166 | const struct bttv_tvnorm *tvnorm; | ||
167 | u32 start0,start1; | ||
168 | s32 count0,count1,count; | ||
169 | |||
170 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; | ||
171 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
172 | f->fmt.vbi.sampling_rate = tvnorm->Fsc; | ||
173 | f->fmt.vbi.samples_per_line = 2048; | ||
174 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
175 | f->fmt.vbi.offset = 244; | ||
176 | f->fmt.vbi.flags = 0; | ||
177 | switch (fh->btv->tvnorm) { | ||
178 | case 1: /* NTSC */ | ||
179 | start0 = 10; | ||
180 | start1 = 273; | ||
181 | break; | ||
182 | case 0: /* PAL */ | ||
183 | case 2: /* SECAM */ | ||
184 | default: | ||
185 | start0 = 7; | ||
186 | start1 = 320; | ||
187 | } | ||
188 | |||
189 | count0 = (f->fmt.vbi.start[0] + f->fmt.vbi.count[0]) - start0; | ||
190 | count1 = (f->fmt.vbi.start[1] + f->fmt.vbi.count[1]) - start1; | ||
191 | count = max(count0,count1); | ||
192 | if (count > VBI_MAXLINES) | ||
193 | count = VBI_MAXLINES; | ||
194 | if (count < 1) | ||
195 | count = 1; | ||
196 | |||
197 | f->fmt.vbi.start[0] = start0; | ||
198 | f->fmt.vbi.start[1] = start1; | ||
199 | f->fmt.vbi.count[0] = count; | ||
200 | f->fmt.vbi.count[1] = count; | ||
201 | } | ||
202 | |||
203 | void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) | ||
204 | { | ||
205 | const struct bttv_tvnorm *tvnorm; | ||
206 | |||
207 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; | ||
208 | memset(f,0,sizeof(*f)); | ||
209 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
210 | f->fmt.vbi.sampling_rate = tvnorm->Fsc; | ||
211 | f->fmt.vbi.samples_per_line = 2048; | ||
212 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
213 | f->fmt.vbi.offset = 244; | ||
214 | f->fmt.vbi.count[0] = fh->lines; | ||
215 | f->fmt.vbi.count[1] = fh->lines; | ||
216 | f->fmt.vbi.flags = 0; | ||
217 | switch (fh->btv->tvnorm) { | ||
218 | case 1: /* NTSC */ | ||
219 | f->fmt.vbi.start[0] = 10; | ||
220 | f->fmt.vbi.start[1] = 273; | ||
221 | break; | ||
222 | case 0: /* PAL */ | ||
223 | case 2: /* SECAM */ | ||
224 | default: | ||
225 | f->fmt.vbi.start[0] = 7; | ||
226 | f->fmt.vbi.start[1] = 319; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | /* ----------------------------------------------------------------------- */ | ||
231 | /* | ||
232 | * Local variables: | ||
233 | * c-basic-offset: 8 | ||
234 | * End: | ||
235 | */ | ||