~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/media/video/cx88/cx88-vbi.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 */
 
3
#include <linux/kernel.h>
 
4
#include <linux/module.h>
 
5
#include <linux/init.h>
 
6
 
 
7
#include "cx88.h"
 
8
 
 
9
static unsigned int vbibufs = 4;
 
10
module_param(vbibufs,int,0644);
 
11
MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");
 
12
 
 
13
static unsigned int vbi_debug;
 
14
module_param(vbi_debug,int,0644);
 
15
MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]");
 
16
 
 
17
#define dprintk(level,fmt, arg...)      if (vbi_debug >= level) \
 
18
        printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg)
 
19
 
 
20
/* ------------------------------------------------------------------ */
 
21
 
 
22
int cx8800_vbi_fmt (struct file *file, void *priv,
 
23
                                        struct v4l2_format *f)
 
24
{
 
25
        struct cx8800_fh  *fh   = priv;
 
26
        struct cx8800_dev *dev  = fh->dev;
 
27
 
 
28
        f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
 
29
        f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
 
30
        f->fmt.vbi.offset = 244;
 
31
        f->fmt.vbi.count[0] = VBI_LINE_COUNT;
 
32
        f->fmt.vbi.count[1] = VBI_LINE_COUNT;
 
33
 
 
34
        if (dev->core->tvnorm & V4L2_STD_525_60) {
 
35
                /* ntsc */
 
36
                f->fmt.vbi.sampling_rate = 28636363;
 
37
                f->fmt.vbi.start[0] = 10;
 
38
                f->fmt.vbi.start[1] = 273;
 
39
 
 
40
        } else if (dev->core->tvnorm & V4L2_STD_625_50) {
 
41
                /* pal */
 
42
                f->fmt.vbi.sampling_rate = 35468950;
 
43
                f->fmt.vbi.start[0] = 7 -1;
 
44
                f->fmt.vbi.start[1] = 319 -1;
 
45
        }
 
46
        return 0;
 
47
}
 
48
 
 
49
static int cx8800_start_vbi_dma(struct cx8800_dev    *dev,
 
50
                         struct cx88_dmaqueue *q,
 
51
                         struct cx88_buffer   *buf)
 
52
{
 
53
        struct cx88_core *core = dev->core;
 
54
 
 
55
        /* setup fifo + format */
 
56
        cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH24],
 
57
                                buf->vb.width, buf->risc.dma);
 
58
 
 
59
        cx_write(MO_VBOS_CONTROL, ( (1 << 18) |  // comb filter delay fixup
 
60
                                    (1 << 15) |  // enable vbi capture
 
61
                                    (1 << 11) ));
 
62
 
 
63
        /* reset counter */
 
64
        cx_write(MO_VBI_GPCNTRL, GP_COUNT_CONTROL_RESET);
 
65
        q->count = 1;
 
66
 
 
67
        /* enable irqs */
 
68
        cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_VIDINT);
 
69
        cx_set(MO_VID_INTMSK, 0x0f0088);
 
70
 
 
71
        /* enable capture */
 
72
        cx_set(VID_CAPTURE_CONTROL,0x18);
 
73
 
 
74
        /* start dma */
 
75
        cx_set(MO_DEV_CNTRL2, (1<<5));
 
76
        cx_set(MO_VID_DMACNTRL, 0x88);
 
77
 
 
78
        return 0;
 
79
}
 
80
 
 
81
int cx8800_stop_vbi_dma(struct cx8800_dev *dev)
 
82
{
 
83
        struct cx88_core *core = dev->core;
 
84
 
 
85
        /* stop dma */
 
86
        cx_clear(MO_VID_DMACNTRL, 0x88);
 
87
 
 
88
        /* disable capture */
 
89
        cx_clear(VID_CAPTURE_CONTROL,0x18);
 
90
 
 
91
        /* disable irqs */
 
92
        cx_clear(MO_PCI_INTMSK, PCI_INT_VIDINT);
 
93
        cx_clear(MO_VID_INTMSK, 0x0f0088);
 
94
        return 0;
 
95
}
 
96
 
 
97
int cx8800_restart_vbi_queue(struct cx8800_dev    *dev,
 
98
                             struct cx88_dmaqueue *q)
 
99
{
 
100
        struct cx88_buffer *buf;
 
101
 
 
102
        if (list_empty(&q->active))
 
103
                return 0;
 
104
 
 
105
        buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
 
106
        dprintk(2,"restart_queue [%p/%d]: restart dma\n",
 
107
                buf, buf->vb.i);
 
108
        cx8800_start_vbi_dma(dev, q, buf);
 
109
        list_for_each_entry(buf, &q->active, vb.queue)
 
110
                buf->count = q->count++;
 
111
        mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
 
112
        return 0;
 
113
}
 
114
 
 
115
void cx8800_vbi_timeout(unsigned long data)
 
116
{
 
117
        struct cx8800_dev *dev = (struct cx8800_dev*)data;
 
118
        struct cx88_core *core = dev->core;
 
119
        struct cx88_dmaqueue *q = &dev->vbiq;
 
120
        struct cx88_buffer *buf;
 
121
        unsigned long flags;
 
122
 
 
123
        cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH24]);
 
124
 
 
125
        cx_clear(MO_VID_DMACNTRL, 0x88);
 
126
        cx_clear(VID_CAPTURE_CONTROL, 0x18);
 
127
 
 
128
        spin_lock_irqsave(&dev->slock,flags);
 
129
        while (!list_empty(&q->active)) {
 
130
                buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
 
131
                list_del(&buf->vb.queue);
 
132
                buf->vb.state = VIDEOBUF_ERROR;
 
133
                wake_up(&buf->vb.done);
 
134
                printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->core->name,
 
135
                       buf, buf->vb.i, (unsigned long)buf->risc.dma);
 
136
        }
 
137
        cx8800_restart_vbi_queue(dev,q);
 
138
        spin_unlock_irqrestore(&dev->slock,flags);
 
139
}
 
140
 
 
141
/* ------------------------------------------------------------------ */
 
142
 
 
143
static int
 
144
vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
 
145
{
 
146
        *size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
 
147
        if (0 == *count)
 
148
                *count = vbibufs;
 
149
        if (*count < 2)
 
150
                *count = 2;
 
151
        if (*count > 32)
 
152
                *count = 32;
 
153
        return 0;
 
154
}
 
155
 
 
156
static int
 
157
vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
 
158
            enum v4l2_field field)
 
159
{
 
160
        struct cx8800_fh   *fh  = q->priv_data;
 
161
        struct cx8800_dev  *dev = fh->dev;
 
162
        struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
 
163
        unsigned int size;
 
164
        int rc;
 
165
 
 
166
        size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
 
167
        if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
 
168
                return -EINVAL;
 
169
 
 
170
        if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
 
171
                struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 
172
                buf->vb.width  = VBI_LINE_LENGTH;
 
173
                buf->vb.height = VBI_LINE_COUNT;
 
174
                buf->vb.size   = size;
 
175
                buf->vb.field  = V4L2_FIELD_SEQ_TB;
 
176
 
 
177
                if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
 
178
                        goto fail;
 
179
                cx88_risc_buffer(dev->pci, &buf->risc,
 
180
                                 dma->sglist,
 
181
                                 0, buf->vb.width * buf->vb.height,
 
182
                                 buf->vb.width, 0,
 
183
                                 buf->vb.height);
 
184
        }
 
185
        buf->vb.state = VIDEOBUF_PREPARED;
 
186
        return 0;
 
187
 
 
188
 fail:
 
189
        cx88_free_buffer(q,buf);
 
190
        return rc;
 
191
}
 
192
 
 
193
static void
 
194
vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
 
195
{
 
196
        struct cx88_buffer    *buf = container_of(vb,struct cx88_buffer,vb);
 
197
        struct cx88_buffer    *prev;
 
198
        struct cx8800_fh      *fh   = vq->priv_data;
 
199
        struct cx8800_dev     *dev  = fh->dev;
 
200
        struct cx88_dmaqueue  *q    = &dev->vbiq;
 
201
 
 
202
        /* add jump to stopper */
 
203
        buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
 
204
        buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
 
205
 
 
206
        if (list_empty(&q->active)) {
 
207
                list_add_tail(&buf->vb.queue,&q->active);
 
208
                cx8800_start_vbi_dma(dev, q, buf);
 
209
                buf->vb.state = VIDEOBUF_ACTIVE;
 
210
                buf->count    = q->count++;
 
211
                mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
 
212
                dprintk(2,"[%p/%d] vbi_queue - first active\n",
 
213
                        buf, buf->vb.i);
 
214
 
 
215
        } else {
 
216
                prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
 
217
                list_add_tail(&buf->vb.queue,&q->active);
 
218
                buf->vb.state = VIDEOBUF_ACTIVE;
 
219
                buf->count    = q->count++;
 
220
                prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
 
221
                dprintk(2,"[%p/%d] buffer_queue - append to active\n",
 
222
                        buf, buf->vb.i);
 
223
        }
 
224
}
 
225
 
 
226
static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
 
227
{
 
228
        struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
 
229
 
 
230
        cx88_free_buffer(q,buf);
 
231
}
 
232
 
 
233
const struct videobuf_queue_ops cx8800_vbi_qops = {
 
234
        .buf_setup    = vbi_setup,
 
235
        .buf_prepare  = vbi_prepare,
 
236
        .buf_queue    = vbi_queue,
 
237
        .buf_release  = vbi_release,
 
238
};
 
239
 
 
240
/* ------------------------------------------------------------------ */
 
241
/*
 
242
 * Local variables:
 
243
 * c-basic-offset: 8
 
244
 * End:
 
245
 */