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