1 /* 2 * Driver for the Conexant CX23885 PCIe bridge 3 * 4 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22 #include <linux/kernel.h> 23 #include <linux/module.h> 24 #include <linux/moduleparam.h> 25 #include <linux/init.h> 26 27 #include "cx23885.h" 28 29 static unsigned int vbibufs = 4; 30 module_param(vbibufs, int, 0644); 31 MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32"); 32 33 static unsigned int vbi_debug; 34 module_param(vbi_debug, int, 0644); 35 MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]"); 36 37 #define dprintk(level, fmt, arg...)\ 38 do { if (vbi_debug >= level)\ 39 printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ 40 } while (0) 41 42 /* ------------------------------------------------------------------ */ 43 44 #define VBI_LINE_LENGTH 1440 45 #define NTSC_VBI_START_LINE 10 /* line 10 - 21 */ 46 #define NTSC_VBI_END_LINE 21 47 #define NTSC_VBI_LINES (NTSC_VBI_END_LINE - NTSC_VBI_START_LINE + 1) 48 49 50 int cx23885_vbi_fmt(struct file *file, void *priv, 51 struct v4l2_format *f) 52 { 53 struct cx23885_fh *fh = priv; 54 struct cx23885_dev *dev = fh->dev; 55 56 if (dev->tvnorm & V4L2_STD_525_60) { 57 /* ntsc */ 58 f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; 59 f->fmt.vbi.sampling_rate = 27000000; 60 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 61 f->fmt.vbi.offset = 0; 62 f->fmt.vbi.flags = 0; 63 f->fmt.vbi.start[0] = 10; 64 f->fmt.vbi.count[0] = 17; 65 f->fmt.vbi.start[1] = 263 + 10 + 1; 66 f->fmt.vbi.count[1] = 17; 67 } else if (dev->tvnorm & V4L2_STD_625_50) { 68 /* pal */ 69 f->fmt.vbi.sampling_rate = 35468950; 70 f->fmt.vbi.start[0] = 7 - 1; 71 f->fmt.vbi.start[1] = 319 - 1; 72 } 73 74 return 0; 75 } 76 77 /* We're given the Video Interrupt status register. 78 * The cx23885_video_irq() func has already validated 79 * the potential error bits, we just need to 80 * deal with vbi payload and return indication if 81 * we actually processed any payload. 82 */ 83 int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status) 84 { 85 u32 count; 86 int handled = 0; 87 88 if (status & VID_BC_MSK_VBI_RISCI1) { 89 dprintk(1, "%s() VID_BC_MSK_VBI_RISCI1\n", __func__); 90 spin_lock(&dev->slock); 91 count = cx_read(VID_A_GPCNT); 92 cx23885_video_wakeup(dev, &dev->vbiq, count); 93 spin_unlock(&dev->slock); 94 handled++; 95 } 96 97 if (status & VID_BC_MSK_VBI_RISCI2) { 98 dprintk(1, "%s() VID_BC_MSK_VBI_RISCI2\n", __func__); 99 dprintk(2, "stopper vbi\n"); 100 spin_lock(&dev->slock); 101 cx23885_restart_vbi_queue(dev, &dev->vbiq); 102 spin_unlock(&dev->slock); 103 handled++; 104 } 105 106 return handled; 107 } 108 109 static int cx23885_start_vbi_dma(struct cx23885_dev *dev, 110 struct cx23885_dmaqueue *q, 111 struct cx23885_buffer *buf) 112 { 113 dprintk(1, "%s()\n", __func__); 114 115 /* setup fifo + format */ 116 cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02], 117 buf->vb.width, buf->risc.dma); 118 119 /* reset counter */ 120 cx_write(VID_A_GPCNT_CTL, 3); 121 cx_write(VID_A_VBI_CTRL, 3); 122 cx_write(VBI_A_GPCNT_CTL, 3); 123 q->count = 1; 124 125 /* enable irq */ 126 cx23885_irq_add_enable(dev, 0x01); 127 cx_set(VID_A_INT_MSK, 0x000022); 128 129 /* start dma */ 130 cx_set(DEV_CNTRL2, (1<<5)); 131 cx_set(VID_A_DMA_CTL, 0x22); /* FIFO and RISC enable */ 132 133 return 0; 134 } 135 136 137 int cx23885_restart_vbi_queue(struct cx23885_dev *dev, 138 struct cx23885_dmaqueue *q) 139 { 140 struct cx23885_buffer *buf; 141 struct list_head *item; 142 143 if (list_empty(&q->active)) 144 return 0; 145 146 buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue); 147 dprintk(2, "restart_queue [%p/%d]: restart dma\n", 148 buf, buf->vb.i); 149 cx23885_start_vbi_dma(dev, q, buf); 150 list_for_each(item, &q->active) { 151 buf = list_entry(item, struct cx23885_buffer, vb.queue); 152 buf->count = q->count++; 153 } 154 mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30)); 155 return 0; 156 } 157 158 void cx23885_vbi_timeout(unsigned long data) 159 { 160 struct cx23885_dev *dev = (struct cx23885_dev *)data; 161 struct cx23885_dmaqueue *q = &dev->vbiq; 162 struct cx23885_buffer *buf; 163 unsigned long flags; 164 165 /* Stop the VBI engine */ 166 cx_clear(VID_A_DMA_CTL, 0x22); 167 168 spin_lock_irqsave(&dev->slock, flags); 169 while (!list_empty(&q->active)) { 170 buf = list_entry(q->active.next, struct cx23885_buffer, 171 vb.queue); 172 list_del(&buf->vb.queue); 173 buf->vb.state = VIDEOBUF_ERROR; 174 wake_up(&buf->vb.done); 175 printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->name, 176 buf, buf->vb.i, (unsigned long)buf->risc.dma); 177 } 178 cx23885_restart_vbi_queue(dev, q); 179 spin_unlock_irqrestore(&dev->slock, flags); 180 } 181 182 /* ------------------------------------------------------------------ */ 183 #define VBI_LINE_LENGTH 1440 184 #define VBI_LINE_COUNT 17 185 186 static int 187 vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) 188 { 189 *size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; 190 if (0 == *count) 191 *count = vbibufs; 192 if (*count < 2) 193 *count = 2; 194 if (*count > 32) 195 *count = 32; 196 return 0; 197 } 198 199 static int 200 vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, 201 enum v4l2_field field) 202 { 203 struct cx23885_fh *fh = q->priv_data; 204 struct cx23885_dev *dev = fh->dev; 205 struct cx23885_buffer *buf = container_of(vb, 206 struct cx23885_buffer, vb); 207 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); 208 unsigned int size; 209 int rc; 210 211 size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; 212 if (0 != buf->vb.baddr && buf->vb.bsize < size) 213 return -EINVAL; 214 215 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 216 buf->vb.width = VBI_LINE_LENGTH; 217 buf->vb.height = VBI_LINE_COUNT; 218 buf->vb.size = size; 219 buf->vb.field = V4L2_FIELD_SEQ_TB; 220 221 rc = videobuf_iolock(q, &buf->vb, NULL); 222 if (0 != rc) 223 goto fail; 224 cx23885_risc_vbibuffer(dev->pci, &buf->risc, 225 dma->sglist, 226 0, buf->vb.width * buf->vb.height, 227 buf->vb.width, 0, 228 buf->vb.height); 229 } 230 buf->vb.state = VIDEOBUF_PREPARED; 231 return 0; 232 233 fail: 234 cx23885_free_buffer(q, buf); 235 return rc; 236 } 237 238 static void 239 vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) 240 { 241 struct cx23885_buffer *buf = 242 container_of(vb, struct cx23885_buffer, vb); 243 struct cx23885_buffer *prev; 244 struct cx23885_fh *fh = vq->priv_data; 245 struct cx23885_dev *dev = fh->dev; 246 struct cx23885_dmaqueue *q = &dev->vbiq; 247 248 /* add jump to stopper */ 249 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); 250 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); 251 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ 252 253 if (list_empty(&q->active)) { 254 list_add_tail(&buf->vb.queue, &q->active); 255 cx23885_start_vbi_dma(dev, q, buf); 256 buf->vb.state = VIDEOBUF_ACTIVE; 257 buf->count = q->count++; 258 mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30)); 259 dprintk(2, "[%p/%d] vbi_queue - first active\n", 260 buf, buf->vb.i); 261 262 } else { 263 prev = list_entry(q->active.prev, struct cx23885_buffer, 264 vb.queue); 265 list_add_tail(&buf->vb.queue, &q->active); 266 buf->vb.state = VIDEOBUF_ACTIVE; 267 buf->count = q->count++; 268 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); 269 prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63-32 */ 270 dprintk(2, "[%p/%d] buffer_queue - append to active\n", 271 buf, buf->vb.i); 272 } 273 } 274 275 static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb) 276 { 277 struct cx23885_buffer *buf = 278 container_of(vb, struct cx23885_buffer, vb); 279 280 cx23885_free_buffer(q, buf); 281 } 282 283 struct videobuf_queue_ops cx23885_vbi_qops = { 284 .buf_setup = vbi_setup, 285 .buf_prepare = vbi_prepare, 286 .buf_queue = vbi_queue, 287 .buf_release = vbi_release, 288 }; 289 290 /* ------------------------------------------------------------------ */ 291 /* 292 * Local variables: 293 * c-basic-offset: 8 294 * End: 295 */ 296