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 vbi_debug; 10 module_param(vbi_debug,int,0644); 11 MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); 12 13 #define dprintk(level,fmt, arg...) if (vbi_debug >= level) \ 14 printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg) 15 16 /* ------------------------------------------------------------------ */ 17 18 int cx8800_vbi_fmt (struct file *file, void *priv, 19 struct v4l2_format *f) 20 { 21 struct cx8800_dev *dev = video_drvdata(file); 22 23 f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; 24 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 25 f->fmt.vbi.offset = 244; 26 27 if (dev->core->tvnorm & V4L2_STD_525_60) { 28 /* ntsc */ 29 f->fmt.vbi.sampling_rate = 28636363; 30 f->fmt.vbi.start[0] = 10; 31 f->fmt.vbi.start[1] = 273; 32 f->fmt.vbi.count[0] = VBI_LINE_NTSC_COUNT; 33 f->fmt.vbi.count[1] = VBI_LINE_NTSC_COUNT; 34 35 } else if (dev->core->tvnorm & V4L2_STD_625_50) { 36 /* pal */ 37 f->fmt.vbi.sampling_rate = 35468950; 38 f->fmt.vbi.start[0] = V4L2_VBI_ITU_625_F1_START + 5; 39 f->fmt.vbi.start[1] = V4L2_VBI_ITU_625_F2_START + 5; 40 f->fmt.vbi.count[0] = VBI_LINE_PAL_COUNT; 41 f->fmt.vbi.count[1] = VBI_LINE_PAL_COUNT; 42 } 43 return 0; 44 } 45 46 static int cx8800_start_vbi_dma(struct cx8800_dev *dev, 47 struct cx88_dmaqueue *q, 48 struct cx88_buffer *buf) 49 { 50 struct cx88_core *core = dev->core; 51 52 /* setup fifo + format */ 53 cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH24], 54 VBI_LINE_LENGTH, buf->risc.dma); 55 56 cx_write(MO_VBOS_CONTROL, ( (1 << 18) | // comb filter delay fixup 57 (1 << 15) | // enable vbi capture 58 (1 << 11) )); 59 60 /* reset counter */ 61 cx_write(MO_VBI_GPCNTRL, GP_COUNT_CONTROL_RESET); 62 q->count = 0; 63 64 /* enable irqs */ 65 cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_VIDINT); 66 cx_set(MO_VID_INTMSK, 0x0f0088); 67 68 /* enable capture */ 69 cx_set(VID_CAPTURE_CONTROL,0x18); 70 71 /* start dma */ 72 cx_set(MO_DEV_CNTRL2, (1<<5)); 73 cx_set(MO_VID_DMACNTRL, 0x88); 74 75 return 0; 76 } 77 78 void cx8800_stop_vbi_dma(struct cx8800_dev *dev) 79 { 80 struct cx88_core *core = dev->core; 81 82 /* stop dma */ 83 cx_clear(MO_VID_DMACNTRL, 0x88); 84 85 /* disable capture */ 86 cx_clear(VID_CAPTURE_CONTROL,0x18); 87 88 /* disable irqs */ 89 cx_clear(MO_PCI_INTMSK, PCI_INT_VIDINT); 90 cx_clear(MO_VID_INTMSK, 0x0f0088); 91 } 92 93 int cx8800_restart_vbi_queue(struct cx8800_dev *dev, 94 struct cx88_dmaqueue *q) 95 { 96 struct cx88_buffer *buf; 97 98 if (list_empty(&q->active)) 99 return 0; 100 101 buf = list_entry(q->active.next, struct cx88_buffer, list); 102 dprintk(2,"restart_queue [%p/%d]: restart dma\n", 103 buf, buf->vb.v4l2_buf.index); 104 cx8800_start_vbi_dma(dev, q, buf); 105 return 0; 106 } 107 108 /* ------------------------------------------------------------------ */ 109 110 static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, 111 unsigned int *num_buffers, unsigned int *num_planes, 112 unsigned int sizes[], void *alloc_ctxs[]) 113 { 114 struct cx8800_dev *dev = q->drv_priv; 115 116 *num_planes = 1; 117 if (dev->core->tvnorm & V4L2_STD_525_60) 118 sizes[0] = VBI_LINE_NTSC_COUNT * VBI_LINE_LENGTH * 2; 119 else 120 sizes[0] = VBI_LINE_PAL_COUNT * VBI_LINE_LENGTH * 2; 121 alloc_ctxs[0] = dev->alloc_ctx; 122 return 0; 123 } 124 125 126 static int buffer_prepare(struct vb2_buffer *vb) 127 { 128 struct cx8800_dev *dev = vb->vb2_queue->drv_priv; 129 struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); 130 struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); 131 unsigned int lines; 132 unsigned int size; 133 134 if (dev->core->tvnorm & V4L2_STD_525_60) 135 lines = VBI_LINE_NTSC_COUNT; 136 else 137 lines = VBI_LINE_PAL_COUNT; 138 size = lines * VBI_LINE_LENGTH * 2; 139 if (vb2_plane_size(vb, 0) < size) 140 return -EINVAL; 141 vb2_set_plane_payload(vb, 0, size); 142 143 cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, 144 0, VBI_LINE_LENGTH * lines, 145 VBI_LINE_LENGTH, 0, 146 lines); 147 return 0; 148 } 149 150 static void buffer_finish(struct vb2_buffer *vb) 151 { 152 struct cx8800_dev *dev = vb->vb2_queue->drv_priv; 153 struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); 154 struct cx88_riscmem *risc = &buf->risc; 155 156 if (risc->cpu) 157 pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); 158 memset(risc, 0, sizeof(*risc)); 159 } 160 161 static void buffer_queue(struct vb2_buffer *vb) 162 { 163 struct cx8800_dev *dev = vb->vb2_queue->drv_priv; 164 struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); 165 struct cx88_buffer *prev; 166 struct cx88_dmaqueue *q = &dev->vbiq; 167 168 /* add jump to start */ 169 buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 8); 170 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC); 171 buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 8); 172 173 if (list_empty(&q->active)) { 174 list_add_tail(&buf->list, &q->active); 175 cx8800_start_vbi_dma(dev, q, buf); 176 dprintk(2,"[%p/%d] vbi_queue - first active\n", 177 buf, buf->vb.v4l2_buf.index); 178 179 } else { 180 buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1); 181 prev = list_entry(q->active.prev, struct cx88_buffer, list); 182 list_add_tail(&buf->list, &q->active); 183 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); 184 dprintk(2,"[%p/%d] buffer_queue - append to active\n", 185 buf, buf->vb.v4l2_buf.index); 186 } 187 } 188 189 static int start_streaming(struct vb2_queue *q, unsigned int count) 190 { 191 struct cx8800_dev *dev = q->drv_priv; 192 struct cx88_dmaqueue *dmaq = &dev->vbiq; 193 struct cx88_buffer *buf = list_entry(dmaq->active.next, 194 struct cx88_buffer, list); 195 196 cx8800_start_vbi_dma(dev, dmaq, buf); 197 return 0; 198 } 199 200 static void stop_streaming(struct vb2_queue *q) 201 { 202 struct cx8800_dev *dev = q->drv_priv; 203 struct cx88_core *core = dev->core; 204 struct cx88_dmaqueue *dmaq = &dev->vbiq; 205 unsigned long flags; 206 207 cx_clear(MO_VID_DMACNTRL, 0x11); 208 cx_clear(VID_CAPTURE_CONTROL, 0x06); 209 cx8800_stop_vbi_dma(dev); 210 spin_lock_irqsave(&dev->slock, flags); 211 while (!list_empty(&dmaq->active)) { 212 struct cx88_buffer *buf = list_entry(dmaq->active.next, 213 struct cx88_buffer, list); 214 215 list_del(&buf->list); 216 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); 217 } 218 spin_unlock_irqrestore(&dev->slock, flags); 219 } 220 221 const struct vb2_ops cx8800_vbi_qops = { 222 .queue_setup = queue_setup, 223 .buf_prepare = buffer_prepare, 224 .buf_finish = buffer_finish, 225 .buf_queue = buffer_queue, 226 .wait_prepare = vb2_ops_wait_prepare, 227 .wait_finish = vb2_ops_wait_finish, 228 .start_streaming = start_streaming, 229 .stop_streaming = stop_streaming, 230 }; 231