Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/cpufreq
[linux-2.6] / drivers / media / video / bt8xx / bttv-vbi.c
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/interrupt.h>
29 #include <linux/kdev_t.h>
30 #include <asm/io.h>
31 #include "bttvp.h"
32
33 /* Offset from line sync pulse leading edge (0H) to start of VBI capture,
34    in fCLKx2 pixels.  According to the datasheet, VBI capture starts
35    VBI_HDELAY fCLKx1 pixels from the tailing edgeof /HRESET, and /HRESET
36    is 64 fCLKx1 pixels wide.  VBI_HDELAY is set to 0, so this should be
37    (64 + 0) * 2 = 128 fCLKx2 pixels.  But it's not!  The datasheet is
38    Just Plain Wrong.  The real value appears to be different for
39    different revisions of the bt8x8 chips, and to be affected by the
40    horizontal scaling factor.  Experimentally, the value is measured
41    to be about 244.  */
42 #define VBI_OFFSET 244
43
44 #define VBI_DEFLINES 16
45 #define VBI_MAXLINES 32
46
47 static unsigned int vbibufs = 4;
48 static unsigned int vbi_debug = 0;
49
50 module_param(vbibufs,   int, 0444);
51 module_param(vbi_debug, int, 0644);
52 MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32, default 4");
53 MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)");
54
55 #ifdef dprintk
56 # undef dprintk
57 #endif
58 #define dprintk(fmt, arg...)    if (vbi_debug) \
59         printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg)
60
61 /* ----------------------------------------------------------------------- */
62 /* vbi risc code + mm                                                      */
63
64 static int
65 vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines)
66 {
67         int bpl = 2048;
68
69         bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
70                          0, bpl-4, 4, lines);
71         bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
72                          lines * bpl, bpl-4, 4, lines);
73         return 0;
74 }
75
76 static int vbi_buffer_setup(struct videobuf_queue *q,
77                             unsigned int *count, unsigned int *size)
78 {
79         struct bttv_fh *fh = q->priv_data;
80         struct bttv *btv = fh->btv;
81
82         if (0 == *count)
83                 *count = vbibufs;
84         *size = fh->lines * 2 * 2048;
85         dprintk("setup: lines=%d\n",fh->lines);
86         return 0;
87 }
88
89 static int vbi_buffer_prepare(struct videobuf_queue *q,
90                               struct videobuf_buffer *vb,
91                               enum v4l2_field field)
92 {
93         struct bttv_fh *fh = q->priv_data;
94         struct bttv *btv = fh->btv;
95         struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
96         int rc;
97
98         buf->vb.size = fh->lines * 2 * 2048;
99         if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
100                 return -EINVAL;
101
102         if (STATE_NEEDS_INIT == buf->vb.state) {
103                 if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
104                         goto fail;
105                 if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
106                         goto fail;
107         }
108         buf->vb.state = STATE_PREPARED;
109         buf->vb.field = field;
110         dprintk("buf prepare %p: top=%p bottom=%p field=%s\n",
111                 vb, &buf->top, &buf->bottom,
112                 v4l2_field_names[buf->vb.field]);
113         return 0;
114
115  fail:
116         bttv_dma_free(q,btv,buf);
117         return rc;
118 }
119
120 static void
121 vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
122 {
123         struct bttv_fh *fh = q->priv_data;
124         struct bttv *btv = fh->btv;
125         struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
126
127         dprintk("queue %p\n",vb);
128         buf->vb.state = STATE_QUEUED;
129         list_add_tail(&buf->vb.queue,&btv->vcapture);
130         if (NULL == btv->cvbi) {
131                 fh->btv->loop_irq |= 4;
132                 bttv_set_dma(btv,0x0c);
133         }
134 }
135
136 static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
137 {
138         struct bttv_fh *fh = q->priv_data;
139         struct bttv *btv = fh->btv;
140         struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
141
142         dprintk("free %p\n",vb);
143         bttv_dma_free(&fh->cap,fh->btv,buf);
144 }
145
146 struct videobuf_queue_ops bttv_vbi_qops = {
147         .buf_setup    = vbi_buffer_setup,
148         .buf_prepare  = vbi_buffer_prepare,
149         .buf_queue    = vbi_buffer_queue,
150         .buf_release  = vbi_buffer_release,
151 };
152
153 /* ----------------------------------------------------------------------- */
154
155 void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines)
156 {
157         int vdelay;
158
159         if (lines < 1)
160                 lines = 1;
161         if (lines > VBI_MAXLINES)
162                 lines = VBI_MAXLINES;
163         fh->lines = lines;
164
165         vdelay = btread(BT848_E_VDELAY_LO);
166         if (vdelay < lines*2) {
167                 vdelay = lines*2;
168                 btwrite(vdelay,BT848_E_VDELAY_LO);
169                 btwrite(vdelay,BT848_O_VDELAY_LO);
170         }
171 }
172
173 void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f)
174 {
175         const struct bttv_tvnorm *tvnorm;
176         s64 count0,count1,count;
177
178         tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
179         f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
180         f->fmt.vbi.sampling_rate    = tvnorm->Fsc;
181         f->fmt.vbi.samples_per_line = 2048;
182         f->fmt.vbi.sample_format    = V4L2_PIX_FMT_GREY;
183         f->fmt.vbi.offset           = VBI_OFFSET;
184         f->fmt.vbi.flags            = 0;
185
186         /* s64 to prevent overflow. */
187         count0 = (s64) f->fmt.vbi.start[0] + f->fmt.vbi.count[0]
188                 - tvnorm->vbistart[0];
189         count1 = (s64) f->fmt.vbi.start[1] + f->fmt.vbi.count[1]
190                 - tvnorm->vbistart[1];
191         count  = clamp (max (count0, count1), (s64) 1, (s64) VBI_MAXLINES);
192
193         f->fmt.vbi.start[0] = tvnorm->vbistart[0];
194         f->fmt.vbi.start[1] = tvnorm->vbistart[1];
195         f->fmt.vbi.count[0] = count;
196         f->fmt.vbi.count[1] = count;
197
198         f->fmt.vbi.reserved[0] = 0;
199         f->fmt.vbi.reserved[1] = 0;
200 }
201
202 void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f)
203 {
204         const struct bttv_tvnorm *tvnorm;
205
206         tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
207         memset(f,0,sizeof(*f));
208         f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
209         f->fmt.vbi.sampling_rate    = tvnorm->Fsc;
210         f->fmt.vbi.samples_per_line = 2048;
211         f->fmt.vbi.sample_format    = V4L2_PIX_FMT_GREY;
212         f->fmt.vbi.offset           = VBI_OFFSET;
213         f->fmt.vbi.start[0]         = tvnorm->vbistart[0];
214         f->fmt.vbi.start[1]         = tvnorm->vbistart[1];
215         f->fmt.vbi.count[0]         = fh->lines;
216         f->fmt.vbi.count[1]         = fh->lines;
217         f->fmt.vbi.flags            = 0;
218 }
219
220 /* ----------------------------------------------------------------------- */
221 /*
222  * Local variables:
223  * c-basic-offset: 8
224  * End:
225  */