diff options
author | Manu Abraham <manu@linuxtv.org> | 2006-03-17 10:07:22 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-03-24 14:26:50 -0500 |
commit | faecfb1760325613debd8df9b9374ce4a28c01d9 (patch) | |
tree | 844e0446e82f07c5d8007d62f7e3a842987e194b /drivers/media/video/bt8xx/bttv-vbi.c | |
parent | 280323ddbc595c463f89c30f3f0f823b076bb4e3 (diff) |
V4L/DVB (3539): Move bttv fragments to bt8xx/
Signed-off-by: Manu Abraham <manu@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/bt8xx/bttv-vbi.c')
-rw-r--r-- | drivers/media/video/bt8xx/bttv-vbi.c | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c new file mode 100644 index 000000000000..e20ff238e409 --- /dev/null +++ b/drivers/media/video/bt8xx/bttv-vbi.c | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | |||
3 | bttv - Bt848 frame grabber driver | ||
4 | vbi interface | ||
5 | |||
6 | (c) 2002 Gerd Knorr <kraxel@bytesex.org> | ||
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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/moduleparam.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/fs.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/kdev_t.h> | ||
31 | #include <asm/io.h> | ||
32 | #include "bttvp.h" | ||
33 | |||
34 | /* Offset from line sync pulse leading edge (0H) in 1 / sampling_rate: | ||
35 | bt8x8 /HRESET pulse starts at 0H and has length 64 / fCLKx1 (E|O_VTC | ||
36 | HSFMT = 0). VBI_HDELAY (always 0) is an offset from the trailing edge | ||
37 | of /HRESET in 1 / fCLKx1, and the sampling_rate tvnorm->Fsc is fCLKx2. */ | ||
38 | #define VBI_OFFSET ((64 + 0) * 2) | ||
39 | |||
40 | #define VBI_DEFLINES 16 | ||
41 | #define VBI_MAXLINES 32 | ||
42 | |||
43 | static unsigned int vbibufs = 4; | ||
44 | static unsigned int vbi_debug = 0; | ||
45 | |||
46 | module_param(vbibufs, int, 0444); | ||
47 | module_param(vbi_debug, int, 0644); | ||
48 | MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32, default 4"); | ||
49 | MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)"); | ||
50 | |||
51 | #ifdef dprintk | ||
52 | # undef dprintk | ||
53 | #endif | ||
54 | #define dprintk(fmt, arg...) if (vbi_debug) \ | ||
55 | printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg) | ||
56 | |||
57 | /* ----------------------------------------------------------------------- */ | ||
58 | /* vbi risc code + mm */ | ||
59 | |||
60 | static int | ||
61 | vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines) | ||
62 | { | ||
63 | int bpl = 2048; | ||
64 | |||
65 | bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist, | ||
66 | 0, bpl-4, 4, lines); | ||
67 | bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist, | ||
68 | lines * bpl, bpl-4, 4, lines); | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static int vbi_buffer_setup(struct videobuf_queue *q, | ||
73 | unsigned int *count, unsigned int *size) | ||
74 | { | ||
75 | struct bttv_fh *fh = q->priv_data; | ||
76 | struct bttv *btv = fh->btv; | ||
77 | |||
78 | if (0 == *count) | ||
79 | *count = vbibufs; | ||
80 | *size = fh->lines * 2 * 2048; | ||
81 | dprintk("setup: lines=%d\n",fh->lines); | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int vbi_buffer_prepare(struct videobuf_queue *q, | ||
86 | struct videobuf_buffer *vb, | ||
87 | enum v4l2_field field) | ||
88 | { | ||
89 | struct bttv_fh *fh = q->priv_data; | ||
90 | struct bttv *btv = fh->btv; | ||
91 | struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); | ||
92 | int rc; | ||
93 | |||
94 | buf->vb.size = fh->lines * 2 * 2048; | ||
95 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | ||
96 | return -EINVAL; | ||
97 | |||
98 | if (STATE_NEEDS_INIT == buf->vb.state) { | ||
99 | if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) | ||
100 | goto fail; | ||
101 | if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines))) | ||
102 | goto fail; | ||
103 | } | ||
104 | buf->vb.state = STATE_PREPARED; | ||
105 | buf->vb.field = field; | ||
106 | dprintk("buf prepare %p: top=%p bottom=%p field=%s\n", | ||
107 | vb, &buf->top, &buf->bottom, | ||
108 | v4l2_field_names[buf->vb.field]); | ||
109 | return 0; | ||
110 | |||
111 | fail: | ||
112 | bttv_dma_free(q,btv,buf); | ||
113 | return rc; | ||
114 | } | ||
115 | |||
116 | static void | ||
117 | vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | ||
118 | { | ||
119 | struct bttv_fh *fh = q->priv_data; | ||
120 | struct bttv *btv = fh->btv; | ||
121 | struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); | ||
122 | |||
123 | dprintk("queue %p\n",vb); | ||
124 | buf->vb.state = STATE_QUEUED; | ||
125 | list_add_tail(&buf->vb.queue,&btv->vcapture); | ||
126 | if (NULL == btv->cvbi) { | ||
127 | fh->btv->loop_irq |= 4; | ||
128 | bttv_set_dma(btv,0x0c); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | ||
133 | { | ||
134 | struct bttv_fh *fh = q->priv_data; | ||
135 | struct bttv *btv = fh->btv; | ||
136 | struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); | ||
137 | |||
138 | dprintk("free %p\n",vb); | ||
139 | bttv_dma_free(&fh->cap,fh->btv,buf); | ||
140 | } | ||
141 | |||
142 | struct videobuf_queue_ops bttv_vbi_qops = { | ||
143 | .buf_setup = vbi_buffer_setup, | ||
144 | .buf_prepare = vbi_buffer_prepare, | ||
145 | .buf_queue = vbi_buffer_queue, | ||
146 | .buf_release = vbi_buffer_release, | ||
147 | }; | ||
148 | |||
149 | /* ----------------------------------------------------------------------- */ | ||
150 | |||
151 | void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines) | ||
152 | { | ||
153 | int vdelay; | ||
154 | |||
155 | if (lines < 1) | ||
156 | lines = 1; | ||
157 | if (lines > VBI_MAXLINES) | ||
158 | lines = VBI_MAXLINES; | ||
159 | fh->lines = lines; | ||
160 | |||
161 | vdelay = btread(BT848_E_VDELAY_LO); | ||
162 | if (vdelay < lines*2) { | ||
163 | vdelay = lines*2; | ||
164 | btwrite(vdelay,BT848_E_VDELAY_LO); | ||
165 | btwrite(vdelay,BT848_O_VDELAY_LO); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f) | ||
170 | { | ||
171 | const struct bttv_tvnorm *tvnorm; | ||
172 | s64 count0,count1,count; | ||
173 | |||
174 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; | ||
175 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
176 | f->fmt.vbi.sampling_rate = tvnorm->Fsc; | ||
177 | f->fmt.vbi.samples_per_line = 2048; | ||
178 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
179 | f->fmt.vbi.offset = VBI_OFFSET; | ||
180 | f->fmt.vbi.flags = 0; | ||
181 | |||
182 | /* s64 to prevent overflow. */ | ||
183 | count0 = (s64) f->fmt.vbi.start[0] + f->fmt.vbi.count[0] | ||
184 | - tvnorm->vbistart[0]; | ||
185 | count1 = (s64) f->fmt.vbi.start[1] + f->fmt.vbi.count[1] | ||
186 | - tvnorm->vbistart[1]; | ||
187 | count = clamp (max (count0, count1), 1LL, (s64) VBI_MAXLINES); | ||
188 | |||
189 | f->fmt.vbi.start[0] = tvnorm->vbistart[0]; | ||
190 | f->fmt.vbi.start[1] = tvnorm->vbistart[1]; | ||
191 | f->fmt.vbi.count[0] = count; | ||
192 | f->fmt.vbi.count[1] = count; | ||
193 | |||
194 | f->fmt.vbi.reserved[0] = 0; | ||
195 | f->fmt.vbi.reserved[1] = 0; | ||
196 | } | ||
197 | |||
198 | void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) | ||
199 | { | ||
200 | const struct bttv_tvnorm *tvnorm; | ||
201 | |||
202 | tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; | ||
203 | memset(f,0,sizeof(*f)); | ||
204 | f->type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
205 | f->fmt.vbi.sampling_rate = tvnorm->Fsc; | ||
206 | f->fmt.vbi.samples_per_line = 2048; | ||
207 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
208 | f->fmt.vbi.offset = VBI_OFFSET; | ||
209 | f->fmt.vbi.start[0] = tvnorm->vbistart[0]; | ||
210 | f->fmt.vbi.start[1] = tvnorm->vbistart[1]; | ||
211 | f->fmt.vbi.count[0] = fh->lines; | ||
212 | f->fmt.vbi.count[1] = fh->lines; | ||
213 | f->fmt.vbi.flags = 0; | ||
214 | } | ||
215 | |||
216 | /* ----------------------------------------------------------------------- */ | ||
217 | /* | ||
218 | * Local variables: | ||
219 | * c-basic-offset: 8 | ||
220 | * End: | ||
221 | */ | ||