diff options
-rw-r--r-- | drivers/media/pci/cx23885/Kconfig | 4 | ||||
-rw-r--r-- | drivers/media/pci/cx23885/altera-ci.c | 4 | ||||
-rw-r--r-- | drivers/media/pci/cx23885/cx23885-417.c | 312 | ||||
-rw-r--r-- | drivers/media/pci/cx23885/cx23885-alsa.c | 4 | ||||
-rw-r--r-- | drivers/media/pci/cx23885/cx23885-core.c | 305 | ||||
-rw-r--r-- | drivers/media/pci/cx23885/cx23885-dvb.c | 131 | ||||
-rw-r--r-- | drivers/media/pci/cx23885/cx23885-vbi.c | 275 | ||||
-rw-r--r-- | drivers/media/pci/cx23885/cx23885-video.c | 810 | ||||
-rw-r--r-- | drivers/media/pci/cx23885/cx23885.h | 61 |
9 files changed, 655 insertions, 1251 deletions
diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig index e12c006e6e2d..38c3b7bc7c2a 100644 --- a/drivers/media/pci/cx23885/Kconfig +++ b/drivers/media/pci/cx23885/Kconfig | |||
@@ -7,8 +7,8 @@ config VIDEO_CX23885 | |||
7 | select VIDEO_TUNER | 7 | select VIDEO_TUNER |
8 | select VIDEO_TVEEPROM | 8 | select VIDEO_TVEEPROM |
9 | depends on RC_CORE | 9 | depends on RC_CORE |
10 | select VIDEOBUF_DVB | 10 | select VIDEOBUF2_DVB |
11 | select VIDEOBUF_DMA_SG | 11 | select VIDEOBUF2_DMA_SG |
12 | select VIDEO_CX25840 | 12 | select VIDEO_CX25840 |
13 | select VIDEO_CX2341X | 13 | select VIDEO_CX2341X |
14 | select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT | 14 | select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT |
diff --git a/drivers/media/pci/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c index 8302d444a0ba..2bbbf545b042 100644 --- a/drivers/media/pci/cx23885/altera-ci.c +++ b/drivers/media/pci/cx23885/altera-ci.c | |||
@@ -48,8 +48,8 @@ | |||
48 | * | DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0| | 48 | * | DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0| |
49 | * +-------+-------+-------+-------+-------+-------+-------+-------+ | 49 | * +-------+-------+-------+-------+-------+-------+-------+-------+ |
50 | */ | 50 | */ |
51 | #include <media/videobuf-dma-sg.h> | 51 | #include <dvb_demux.h> |
52 | #include <media/videobuf-dvb.h> | 52 | #include <dvb_frontend.h> |
53 | #include "altera-ci.h" | 53 | #include "altera-ci.h" |
54 | #include "dvb_ca_en50221.h" | 54 | #include "dvb_ca_en50221.h" |
55 | 55 | ||
diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c index 56673b52c559..f1ef9017e2a7 100644 --- a/drivers/media/pci/cx23885/cx23885-417.c +++ b/drivers/media/pci/cx23885/cx23885-417.c | |||
@@ -1138,47 +1138,100 @@ static int cx23885_initialize_codec(struct cx23885_dev *dev, int startencoder) | |||
1138 | 1138 | ||
1139 | /* ------------------------------------------------------------------ */ | 1139 | /* ------------------------------------------------------------------ */ |
1140 | 1140 | ||
1141 | static int bb_buf_setup(struct videobuf_queue *q, | 1141 | static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, |
1142 | unsigned int *count, unsigned int *size) | 1142 | unsigned int *num_buffers, unsigned int *num_planes, |
1143 | unsigned int sizes[], void *alloc_ctxs[]) | ||
1143 | { | 1144 | { |
1144 | struct cx23885_fh *fh = q->priv_data; | 1145 | struct cx23885_dev *dev = q->drv_priv; |
1145 | 1146 | ||
1146 | fh->q_dev->ts1.ts_packet_size = mpeglinesize; | 1147 | dev->ts1.ts_packet_size = mpeglinesize; |
1147 | fh->q_dev->ts1.ts_packet_count = mpeglines; | 1148 | dev->ts1.ts_packet_count = mpeglines; |
1149 | *num_planes = 1; | ||
1150 | sizes[0] = mpeglinesize * mpeglines; | ||
1151 | *num_buffers = mpegbufs; | ||
1152 | return 0; | ||
1153 | } | ||
1148 | 1154 | ||
1149 | *size = fh->q_dev->ts1.ts_packet_size * fh->q_dev->ts1.ts_packet_count; | 1155 | static int buffer_prepare(struct vb2_buffer *vb) |
1150 | *count = mpegbufs; | 1156 | { |
1157 | struct cx23885_dev *dev = vb->vb2_queue->drv_priv; | ||
1158 | struct cx23885_buffer *buf = | ||
1159 | container_of(vb, struct cx23885_buffer, vb); | ||
1151 | 1160 | ||
1152 | return 0; | 1161 | return cx23885_buf_prepare(buf, &dev->ts1); |
1153 | } | 1162 | } |
1154 | 1163 | ||
1155 | static int bb_buf_prepare(struct videobuf_queue *q, | 1164 | static void buffer_finish(struct vb2_buffer *vb) |
1156 | struct videobuf_buffer *vb, enum v4l2_field field) | ||
1157 | { | 1165 | { |
1158 | struct cx23885_fh *fh = q->priv_data; | 1166 | struct cx23885_dev *dev = vb->vb2_queue->drv_priv; |
1159 | return cx23885_buf_prepare(q, &fh->q_dev->ts1, | 1167 | struct cx23885_buffer *buf = container_of(vb, |
1160 | (struct cx23885_buffer *)vb, | 1168 | struct cx23885_buffer, vb); |
1161 | field); | 1169 | struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); |
1170 | |||
1171 | cx23885_free_buffer(dev, buf); | ||
1172 | |||
1173 | dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); | ||
1162 | } | 1174 | } |
1163 | 1175 | ||
1164 | static void bb_buf_queue(struct videobuf_queue *q, | 1176 | static void buffer_queue(struct vb2_buffer *vb) |
1165 | struct videobuf_buffer *vb) | ||
1166 | { | 1177 | { |
1167 | struct cx23885_fh *fh = q->priv_data; | 1178 | struct cx23885_dev *dev = vb->vb2_queue->drv_priv; |
1168 | cx23885_buf_queue(&fh->q_dev->ts1, (struct cx23885_buffer *)vb); | 1179 | struct cx23885_buffer *buf = container_of(vb, |
1180 | struct cx23885_buffer, vb); | ||
1181 | |||
1182 | cx23885_buf_queue(&dev->ts1, buf); | ||
1183 | } | ||
1184 | |||
1185 | static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count) | ||
1186 | { | ||
1187 | struct cx23885_dev *dev = q->drv_priv; | ||
1188 | struct cx23885_dmaqueue *dmaq = &dev->ts1.mpegq; | ||
1189 | unsigned long flags; | ||
1190 | int ret; | ||
1191 | |||
1192 | ret = cx23885_initialize_codec(dev, 1); | ||
1193 | if (ret == 0) { | ||
1194 | struct cx23885_buffer *buf = list_entry(dmaq->active.next, | ||
1195 | struct cx23885_buffer, queue); | ||
1196 | |||
1197 | cx23885_start_dma(&dev->ts1, dmaq, buf); | ||
1198 | return 0; | ||
1199 | } | ||
1200 | spin_lock_irqsave(&dev->slock, flags); | ||
1201 | while (!list_empty(&dmaq->active)) { | ||
1202 | struct cx23885_buffer *buf = list_entry(dmaq->active.next, | ||
1203 | struct cx23885_buffer, queue); | ||
1204 | |||
1205 | list_del(&buf->queue); | ||
1206 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED); | ||
1207 | } | ||
1208 | spin_unlock_irqrestore(&dev->slock, flags); | ||
1209 | return ret; | ||
1169 | } | 1210 | } |
1170 | 1211 | ||
1171 | static void bb_buf_release(struct videobuf_queue *q, | 1212 | static void cx23885_stop_streaming(struct vb2_queue *q) |
1172 | struct videobuf_buffer *vb) | ||
1173 | { | 1213 | { |
1174 | cx23885_free_buffer(q, (struct cx23885_buffer *)vb); | 1214 | struct cx23885_dev *dev = q->drv_priv; |
1215 | |||
1216 | /* stop mpeg capture */ | ||
1217 | cx23885_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, | ||
1218 | CX23885_END_NOW, CX23885_MPEG_CAPTURE, | ||
1219 | CX23885_RAW_BITS_NONE); | ||
1220 | |||
1221 | msleep(500); | ||
1222 | cx23885_417_check_encoder(dev); | ||
1223 | cx23885_cancel_buffers(&dev->ts1); | ||
1175 | } | 1224 | } |
1176 | 1225 | ||
1177 | static struct videobuf_queue_ops cx23885_qops = { | 1226 | static struct vb2_ops cx23885_qops = { |
1178 | .buf_setup = bb_buf_setup, | 1227 | .queue_setup = queue_setup, |
1179 | .buf_prepare = bb_buf_prepare, | 1228 | .buf_prepare = buffer_prepare, |
1180 | .buf_queue = bb_buf_queue, | 1229 | .buf_finish = buffer_finish, |
1181 | .buf_release = bb_buf_release, | 1230 | .buf_queue = buffer_queue, |
1231 | .wait_prepare = vb2_ops_wait_prepare, | ||
1232 | .wait_finish = vb2_ops_wait_finish, | ||
1233 | .start_streaming = cx23885_start_streaming, | ||
1234 | .stop_streaming = cx23885_stop_streaming, | ||
1182 | }; | 1235 | }; |
1183 | 1236 | ||
1184 | /* ------------------------------------------------------------------ */ | 1237 | /* ------------------------------------------------------------------ */ |
@@ -1316,7 +1369,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
1316 | struct v4l2_format *f) | 1369 | struct v4l2_format *f) |
1317 | { | 1370 | { |
1318 | struct cx23885_dev *dev = video_drvdata(file); | 1371 | struct cx23885_dev *dev = video_drvdata(file); |
1319 | struct cx23885_fh *fh = file->private_data; | ||
1320 | 1372 | ||
1321 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | 1373 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
1322 | f->fmt.pix.bytesperline = 0; | 1374 | f->fmt.pix.bytesperline = 0; |
@@ -1325,9 +1377,9 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
1325 | f->fmt.pix.colorspace = 0; | 1377 | f->fmt.pix.colorspace = 0; |
1326 | f->fmt.pix.width = dev->ts1.width; | 1378 | f->fmt.pix.width = dev->ts1.width; |
1327 | f->fmt.pix.height = dev->ts1.height; | 1379 | f->fmt.pix.height = dev->ts1.height; |
1328 | f->fmt.pix.field = fh->mpegq.field; | 1380 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; |
1329 | dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", | 1381 | dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n", |
1330 | dev->ts1.width, dev->ts1.height, fh->mpegq.field); | 1382 | dev->ts1.width, dev->ts1.height); |
1331 | return 0; | 1383 | return 0; |
1332 | } | 1384 | } |
1333 | 1385 | ||
@@ -1335,15 +1387,15 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
1335 | struct v4l2_format *f) | 1387 | struct v4l2_format *f) |
1336 | { | 1388 | { |
1337 | struct cx23885_dev *dev = video_drvdata(file); | 1389 | struct cx23885_dev *dev = video_drvdata(file); |
1338 | struct cx23885_fh *fh = file->private_data; | ||
1339 | 1390 | ||
1340 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | 1391 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
1341 | f->fmt.pix.bytesperline = 0; | 1392 | f->fmt.pix.bytesperline = 0; |
1342 | f->fmt.pix.sizeimage = | 1393 | f->fmt.pix.sizeimage = |
1343 | dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; | 1394 | dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; |
1344 | f->fmt.pix.colorspace = 0; | 1395 | f->fmt.pix.colorspace = 0; |
1345 | dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", | 1396 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; |
1346 | dev->ts1.width, dev->ts1.height, fh->mpegq.field); | 1397 | dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n", |
1398 | dev->ts1.width, dev->ts1.height); | ||
1347 | return 0; | 1399 | return 0; |
1348 | } | 1400 | } |
1349 | 1401 | ||
@@ -1357,58 +1409,12 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
1357 | f->fmt.pix.sizeimage = | 1409 | f->fmt.pix.sizeimage = |
1358 | dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; | 1410 | dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; |
1359 | f->fmt.pix.colorspace = 0; | 1411 | f->fmt.pix.colorspace = 0; |
1412 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
1360 | dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", | 1413 | dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", |
1361 | f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); | 1414 | f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); |
1362 | return 0; | 1415 | return 0; |
1363 | } | 1416 | } |
1364 | 1417 | ||
1365 | static int vidioc_reqbufs(struct file *file, void *priv, | ||
1366 | struct v4l2_requestbuffers *p) | ||
1367 | { | ||
1368 | struct cx23885_fh *fh = file->private_data; | ||
1369 | |||
1370 | return videobuf_reqbufs(&fh->mpegq, p); | ||
1371 | } | ||
1372 | |||
1373 | static int vidioc_querybuf(struct file *file, void *priv, | ||
1374 | struct v4l2_buffer *p) | ||
1375 | { | ||
1376 | struct cx23885_fh *fh = file->private_data; | ||
1377 | |||
1378 | return videobuf_querybuf(&fh->mpegq, p); | ||
1379 | } | ||
1380 | |||
1381 | static int vidioc_qbuf(struct file *file, void *priv, | ||
1382 | struct v4l2_buffer *p) | ||
1383 | { | ||
1384 | struct cx23885_fh *fh = file->private_data; | ||
1385 | |||
1386 | return videobuf_qbuf(&fh->mpegq, p); | ||
1387 | } | ||
1388 | |||
1389 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | ||
1390 | { | ||
1391 | struct cx23885_fh *fh = priv; | ||
1392 | |||
1393 | return videobuf_dqbuf(&fh->mpegq, b, file->f_flags & O_NONBLOCK); | ||
1394 | } | ||
1395 | |||
1396 | |||
1397 | static int vidioc_streamon(struct file *file, void *priv, | ||
1398 | enum v4l2_buf_type i) | ||
1399 | { | ||
1400 | struct cx23885_fh *fh = file->private_data; | ||
1401 | |||
1402 | return videobuf_streamon(&fh->mpegq); | ||
1403 | } | ||
1404 | |||
1405 | static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | ||
1406 | { | ||
1407 | struct cx23885_fh *fh = file->private_data; | ||
1408 | |||
1409 | return videobuf_streamoff(&fh->mpegq); | ||
1410 | } | ||
1411 | |||
1412 | static int vidioc_log_status(struct file *file, void *priv) | 1418 | static int vidioc_log_status(struct file *file, void *priv) |
1413 | { | 1419 | { |
1414 | struct cx23885_dev *dev = video_drvdata(file); | 1420 | struct cx23885_dev *dev = video_drvdata(file); |
@@ -1420,120 +1426,14 @@ static int vidioc_log_status(struct file *file, void *priv) | |||
1420 | return 0; | 1426 | return 0; |
1421 | } | 1427 | } |
1422 | 1428 | ||
1423 | static int mpeg_open(struct file *file) | ||
1424 | { | ||
1425 | struct cx23885_dev *dev = video_drvdata(file); | ||
1426 | struct video_device *vdev = video_devdata(file); | ||
1427 | struct cx23885_fh *fh; | ||
1428 | |||
1429 | dprintk(2, "%s()\n", __func__); | ||
1430 | |||
1431 | /* allocate + initialize per filehandle data */ | ||
1432 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | ||
1433 | if (!fh) | ||
1434 | return -ENOMEM; | ||
1435 | |||
1436 | v4l2_fh_init(&fh->fh, vdev); | ||
1437 | file->private_data = fh; | ||
1438 | fh->q_dev = dev; | ||
1439 | |||
1440 | videobuf_queue_sg_init(&fh->mpegq, &cx23885_qops, | ||
1441 | &dev->pci->dev, &dev->ts1.slock, | ||
1442 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
1443 | V4L2_FIELD_INTERLACED, | ||
1444 | sizeof(struct cx23885_buffer), | ||
1445 | fh, NULL); | ||
1446 | v4l2_fh_add(&fh->fh); | ||
1447 | return 0; | ||
1448 | } | ||
1449 | |||
1450 | static int mpeg_release(struct file *file) | ||
1451 | { | ||
1452 | struct cx23885_dev *dev = video_drvdata(file); | ||
1453 | struct cx23885_fh *fh = file->private_data; | ||
1454 | |||
1455 | dprintk(2, "%s()\n", __func__); | ||
1456 | |||
1457 | /* FIXME: Review this crap */ | ||
1458 | /* Shut device down on last close */ | ||
1459 | if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) { | ||
1460 | if (atomic_dec_return(&dev->v4l_reader_count) == 0) { | ||
1461 | /* stop mpeg capture */ | ||
1462 | cx23885_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, | ||
1463 | CX23885_END_NOW, CX23885_MPEG_CAPTURE, | ||
1464 | CX23885_RAW_BITS_NONE); | ||
1465 | |||
1466 | msleep(500); | ||
1467 | cx23885_417_check_encoder(dev); | ||
1468 | |||
1469 | cx23885_cancel_buffers(&dev->ts1); | ||
1470 | } | ||
1471 | } | ||
1472 | |||
1473 | if (fh->mpegq.streaming) | ||
1474 | videobuf_streamoff(&fh->mpegq); | ||
1475 | if (fh->mpegq.reading) | ||
1476 | videobuf_read_stop(&fh->mpegq); | ||
1477 | |||
1478 | videobuf_mmap_free(&fh->mpegq); | ||
1479 | v4l2_fh_del(&fh->fh); | ||
1480 | v4l2_fh_exit(&fh->fh); | ||
1481 | file->private_data = NULL; | ||
1482 | kfree(fh); | ||
1483 | |||
1484 | return 0; | ||
1485 | } | ||
1486 | |||
1487 | static ssize_t mpeg_read(struct file *file, char __user *data, | ||
1488 | size_t count, loff_t *ppos) | ||
1489 | { | ||
1490 | struct cx23885_dev *dev = video_drvdata(file); | ||
1491 | struct cx23885_fh *fh = file->private_data; | ||
1492 | |||
1493 | dprintk(2, "%s()\n", __func__); | ||
1494 | |||
1495 | /* Deal w/ A/V decoder * and mpeg encoder sync issues. */ | ||
1496 | /* Start mpeg encoder on first read. */ | ||
1497 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { | ||
1498 | if (atomic_inc_return(&dev->v4l_reader_count) == 1) { | ||
1499 | if (cx23885_initialize_codec(dev, 1) < 0) | ||
1500 | return -EINVAL; | ||
1501 | } | ||
1502 | } | ||
1503 | |||
1504 | return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0, | ||
1505 | file->f_flags & O_NONBLOCK); | ||
1506 | } | ||
1507 | |||
1508 | static unsigned int mpeg_poll(struct file *file, | ||
1509 | struct poll_table_struct *wait) | ||
1510 | { | ||
1511 | struct cx23885_dev *dev = video_drvdata(file); | ||
1512 | struct cx23885_fh *fh = file->private_data; | ||
1513 | |||
1514 | dprintk(2, "%s\n", __func__); | ||
1515 | |||
1516 | return videobuf_poll_stream(file, &fh->mpegq, wait); | ||
1517 | } | ||
1518 | |||
1519 | static int mpeg_mmap(struct file *file, struct vm_area_struct *vma) | ||
1520 | { | ||
1521 | struct cx23885_dev *dev = video_drvdata(file); | ||
1522 | struct cx23885_fh *fh = file->private_data; | ||
1523 | |||
1524 | dprintk(2, "%s()\n", __func__); | ||
1525 | |||
1526 | return videobuf_mmap_mapper(&fh->mpegq, vma); | ||
1527 | } | ||
1528 | |||
1529 | static struct v4l2_file_operations mpeg_fops = { | 1429 | static struct v4l2_file_operations mpeg_fops = { |
1530 | .owner = THIS_MODULE, | 1430 | .owner = THIS_MODULE, |
1531 | .open = mpeg_open, | 1431 | .open = v4l2_fh_open, |
1532 | .release = mpeg_release, | 1432 | .release = vb2_fop_release, |
1533 | .read = mpeg_read, | 1433 | .read = vb2_fop_read, |
1534 | .poll = mpeg_poll, | 1434 | .poll = vb2_fop_poll, |
1535 | .mmap = mpeg_mmap, | ||
1536 | .unlocked_ioctl = video_ioctl2, | 1435 | .unlocked_ioctl = video_ioctl2, |
1436 | .mmap = vb2_fop_mmap, | ||
1537 | }; | 1437 | }; |
1538 | 1438 | ||
1539 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { | 1439 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { |
@@ -1551,12 +1451,13 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { | |||
1551 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | 1451 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, |
1552 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | 1452 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, |
1553 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | 1453 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, |
1554 | .vidioc_reqbufs = vidioc_reqbufs, | 1454 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
1555 | .vidioc_querybuf = vidioc_querybuf, | 1455 | .vidioc_prepare_buf = vb2_ioctl_prepare_buf, |
1556 | .vidioc_qbuf = vidioc_qbuf, | 1456 | .vidioc_querybuf = vb2_ioctl_querybuf, |
1557 | .vidioc_dqbuf = vidioc_dqbuf, | 1457 | .vidioc_qbuf = vb2_ioctl_qbuf, |
1558 | .vidioc_streamon = vidioc_streamon, | 1458 | .vidioc_dqbuf = vb2_ioctl_dqbuf, |
1559 | .vidioc_streamoff = vidioc_streamoff, | 1459 | .vidioc_streamon = vb2_ioctl_streamon, |
1460 | .vidioc_streamoff = vb2_ioctl_streamoff, | ||
1560 | .vidioc_log_status = vidioc_log_status, | 1461 | .vidioc_log_status = vidioc_log_status, |
1561 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1462 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1562 | .vidioc_g_chip_info = cx23885_g_chip_info, | 1463 | .vidioc_g_chip_info = cx23885_g_chip_info, |
@@ -1613,6 +1514,7 @@ int cx23885_417_register(struct cx23885_dev *dev) | |||
1613 | /* FIXME: Port1 hardcoded here */ | 1514 | /* FIXME: Port1 hardcoded here */ |
1614 | int err = -ENODEV; | 1515 | int err = -ENODEV; |
1615 | struct cx23885_tsport *tsport = &dev->ts1; | 1516 | struct cx23885_tsport *tsport = &dev->ts1; |
1517 | struct vb2_queue *q; | ||
1616 | 1518 | ||
1617 | dprintk(1, "%s()\n", __func__); | 1519 | dprintk(1, "%s()\n", __func__); |
1618 | 1520 | ||
@@ -1640,8 +1542,24 @@ int cx23885_417_register(struct cx23885_dev *dev) | |||
1640 | /* Allocate and initialize V4L video device */ | 1542 | /* Allocate and initialize V4L video device */ |
1641 | dev->v4l_device = cx23885_video_dev_alloc(tsport, | 1543 | dev->v4l_device = cx23885_video_dev_alloc(tsport, |
1642 | dev->pci, &cx23885_mpeg_template, "mpeg"); | 1544 | dev->pci, &cx23885_mpeg_template, "mpeg"); |
1545 | q = &dev->vb2_mpegq; | ||
1546 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1547 | q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; | ||
1548 | q->gfp_flags = GFP_DMA32; | ||
1549 | q->min_buffers_needed = 2; | ||
1550 | q->drv_priv = dev; | ||
1551 | q->buf_struct_size = sizeof(struct cx23885_buffer); | ||
1552 | q->ops = &cx23885_qops; | ||
1553 | q->mem_ops = &vb2_dma_sg_memops; | ||
1554 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
1555 | q->lock = &dev->lock; | ||
1556 | |||
1557 | err = vb2_queue_init(q); | ||
1558 | if (err < 0) | ||
1559 | return err; | ||
1643 | video_set_drvdata(dev->v4l_device, dev); | 1560 | video_set_drvdata(dev->v4l_device, dev); |
1644 | dev->v4l_device->lock = &dev->lock; | 1561 | dev->v4l_device->lock = &dev->lock; |
1562 | dev->v4l_device->queue = q; | ||
1645 | err = video_register_device(dev->v4l_device, | 1563 | err = video_register_device(dev->v4l_device, |
1646 | VFL_TYPE_GRABBER, -1); | 1564 | VFL_TYPE_GRABBER, -1); |
1647 | if (err < 0) { | 1565 | if (err < 0) { |
diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c index c17e4740d47c..1b162ee8c8c6 100644 --- a/drivers/media/pci/cx23885/cx23885-alsa.c +++ b/drivers/media/pci/cx23885/cx23885-alsa.c | |||
@@ -389,6 +389,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream, | |||
389 | return -ENOMEM; | 389 | return -ENOMEM; |
390 | 390 | ||
391 | buf->bpl = chip->period_size; | 391 | buf->bpl = chip->period_size; |
392 | chip->buf = buf; | ||
392 | 393 | ||
393 | ret = cx23885_alsa_dma_init(chip, | 394 | ret = cx23885_alsa_dma_init(chip, |
394 | (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); | 395 | (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); |
@@ -409,8 +410,6 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream, | |||
409 | buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | 410 | buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
410 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ | 411 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ |
411 | 412 | ||
412 | chip->buf = buf; | ||
413 | |||
414 | substream->runtime->dma_area = chip->buf->vaddr; | 413 | substream->runtime->dma_area = chip->buf->vaddr; |
415 | substream->runtime->dma_bytes = chip->dma_size; | 414 | substream->runtime->dma_bytes = chip->dma_size; |
416 | substream->runtime->dma_addr = 0; | 415 | substream->runtime->dma_addr = 0; |
@@ -419,6 +418,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream, | |||
419 | 418 | ||
420 | error: | 419 | error: |
421 | kfree(buf); | 420 | kfree(buf); |
421 | chip->buf = NULL; | ||
422 | return ret; | 422 | return ret; |
423 | } | 423 | } |
424 | 424 | ||
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 0b6bbac6990f..8d77a5649777 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c | |||
@@ -416,39 +416,23 @@ static int cx23885_risc_decode(u32 risc) | |||
416 | return incr[risc >> 28] ? incr[risc >> 28] : 1; | 416 | return incr[risc >> 28] ? incr[risc >> 28] : 1; |
417 | } | 417 | } |
418 | 418 | ||
419 | void cx23885_wakeup(struct cx23885_tsport *port, | 419 | static void cx23885_wakeup(struct cx23885_tsport *port, |
420 | struct cx23885_dmaqueue *q, u32 count) | 420 | struct cx23885_dmaqueue *q, u32 count) |
421 | { | 421 | { |
422 | struct cx23885_dev *dev = port->dev; | 422 | struct cx23885_dev *dev = port->dev; |
423 | struct cx23885_buffer *buf; | 423 | struct cx23885_buffer *buf; |
424 | int bc; | ||
425 | 424 | ||
426 | for (bc = 0;; bc++) { | ||
427 | if (list_empty(&q->active)) | ||
428 | break; | ||
429 | buf = list_entry(q->active.next, | ||
430 | struct cx23885_buffer, vb.queue); | ||
431 | |||
432 | /* count comes from the hw and is is 16bit wide -- | ||
433 | * this trick handles wrap-arounds correctly for | ||
434 | * up to 32767 buffers in flight... */ | ||
435 | if ((s16) (count - buf->count) < 0) | ||
436 | break; | ||
437 | |||
438 | v4l2_get_timestamp(&buf->vb.ts); | ||
439 | dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i, | ||
440 | count, buf->count); | ||
441 | buf->vb.state = VIDEOBUF_DONE; | ||
442 | list_del(&buf->vb.queue); | ||
443 | wake_up(&buf->vb.done); | ||
444 | } | ||
445 | if (list_empty(&q->active)) | 425 | if (list_empty(&q->active)) |
446 | del_timer(&q->timeout); | 426 | return; |
447 | else | 427 | buf = list_entry(q->active.next, |
448 | mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); | 428 | struct cx23885_buffer, queue); |
449 | if (bc != 1) | 429 | |
450 | printk(KERN_WARNING "%s: %d buffers handled (should be 1)\n", | 430 | v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); |
451 | __func__, bc); | 431 | buf->vb.v4l2_buf.sequence = q->count++; |
432 | dprintk(1, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.v4l2_buf.index, | ||
433 | count, q->count); | ||
434 | list_del(&buf->queue); | ||
435 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); | ||
452 | } | 436 | } |
453 | 437 | ||
454 | int cx23885_sram_channel_setup(struct cx23885_dev *dev, | 438 | int cx23885_sram_channel_setup(struct cx23885_dev *dev, |
@@ -478,8 +462,8 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, | |||
478 | lines = 6; | 462 | lines = 6; |
479 | BUG_ON(lines < 2); | 463 | BUG_ON(lines < 2); |
480 | 464 | ||
481 | cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); | 465 | cx_write(8 + 0, RISC_JUMP | RISC_CNT_RESET); |
482 | cx_write(8 + 4, 8); | 466 | cx_write(8 + 4, 12); |
483 | cx_write(8 + 8, 0); | 467 | cx_write(8 + 8, 0); |
484 | 468 | ||
485 | /* write CDT */ | 469 | /* write CDT */ |
@@ -695,10 +679,6 @@ static int get_resources(struct cx23885_dev *dev) | |||
695 | return -EBUSY; | 679 | return -EBUSY; |
696 | } | 680 | } |
697 | 681 | ||
698 | static void cx23885_timeout(unsigned long data); | ||
699 | int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | ||
700 | u32 reg, u32 mask, u32 value); | ||
701 | |||
702 | static int cx23885_init_tsport(struct cx23885_dev *dev, | 682 | static int cx23885_init_tsport(struct cx23885_dev *dev, |
703 | struct cx23885_tsport *port, int portno) | 683 | struct cx23885_tsport *port, int portno) |
704 | { | 684 | { |
@@ -715,11 +695,6 @@ static int cx23885_init_tsport(struct cx23885_dev *dev, | |||
715 | port->nr = portno; | 695 | port->nr = portno; |
716 | 696 | ||
717 | INIT_LIST_HEAD(&port->mpegq.active); | 697 | INIT_LIST_HEAD(&port->mpegq.active); |
718 | INIT_LIST_HEAD(&port->mpegq.queued); | ||
719 | port->mpegq.timeout.function = cx23885_timeout; | ||
720 | port->mpegq.timeout.data = (unsigned long)port; | ||
721 | init_timer(&port->mpegq.timeout); | ||
722 | |||
723 | mutex_init(&port->frontends.lock); | 698 | mutex_init(&port->frontends.lock); |
724 | INIT_LIST_HEAD(&port->frontends.felist); | 699 | INIT_LIST_HEAD(&port->frontends.felist); |
725 | port->frontends.active_fe_id = 0; | 700 | port->frontends.active_fe_id = 0; |
@@ -772,9 +747,6 @@ static int cx23885_init_tsport(struct cx23885_dev *dev, | |||
772 | BUG(); | 747 | BUG(); |
773 | } | 748 | } |
774 | 749 | ||
775 | cx23885_risc_stopper(dev->pci, &port->mpegq.stopper, | ||
776 | port->reg_dma_ctl, port->dma_ctl_val, 0x00); | ||
777 | |||
778 | return 0; | 750 | return 0; |
779 | } | 751 | } |
780 | 752 | ||
@@ -1085,11 +1057,18 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev) | |||
1085 | static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, | 1057 | static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, |
1086 | unsigned int offset, u32 sync_line, | 1058 | unsigned int offset, u32 sync_line, |
1087 | unsigned int bpl, unsigned int padding, | 1059 | unsigned int bpl, unsigned int padding, |
1088 | unsigned int lines, unsigned int lpi) | 1060 | unsigned int lines, unsigned int lpi, bool jump) |
1089 | { | 1061 | { |
1090 | struct scatterlist *sg; | 1062 | struct scatterlist *sg; |
1091 | unsigned int line, todo, sol; | 1063 | unsigned int line, todo, sol; |
1092 | 1064 | ||
1065 | |||
1066 | if (jump) { | ||
1067 | *(rp++) = cpu_to_le32(RISC_JUMP); | ||
1068 | *(rp++) = cpu_to_le32(0); | ||
1069 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
1070 | } | ||
1071 | |||
1093 | /* sync instruction */ | 1072 | /* sync instruction */ |
1094 | if (sync_line != NO_SYNC_LINE) | 1073 | if (sync_line != NO_SYNC_LINE) |
1095 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); | 1074 | *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); |
@@ -1164,7 +1143,7 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
1164 | /* write and jump need and extra dword */ | 1143 | /* write and jump need and extra dword */ |
1165 | instructions = fields * (1 + ((bpl + padding) * lines) | 1144 | instructions = fields * (1 + ((bpl + padding) * lines) |
1166 | / PAGE_SIZE + lines); | 1145 | / PAGE_SIZE + lines); |
1167 | instructions += 2; | 1146 | instructions += 5; |
1168 | rc = btcx_riscmem_alloc(pci, risc, instructions*12); | 1147 | rc = btcx_riscmem_alloc(pci, risc, instructions*12); |
1169 | if (rc < 0) | 1148 | if (rc < 0) |
1170 | return rc; | 1149 | return rc; |
@@ -1173,10 +1152,10 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
1173 | rp = risc->cpu; | 1152 | rp = risc->cpu; |
1174 | if (UNSET != top_offset) | 1153 | if (UNSET != top_offset) |
1175 | rp = cx23885_risc_field(rp, sglist, top_offset, 0, | 1154 | rp = cx23885_risc_field(rp, sglist, top_offset, 0, |
1176 | bpl, padding, lines, 0); | 1155 | bpl, padding, lines, 0, true); |
1177 | if (UNSET != bottom_offset) | 1156 | if (UNSET != bottom_offset) |
1178 | rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200, | 1157 | rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200, |
1179 | bpl, padding, lines, 0); | 1158 | bpl, padding, lines, 0, UNSET == top_offset); |
1180 | 1159 | ||
1181 | /* save pointer to jmp instruction address */ | 1160 | /* save pointer to jmp instruction address */ |
1182 | risc->jmp = rp; | 1161 | risc->jmp = rp; |
@@ -1200,7 +1179,7 @@ int cx23885_risc_databuffer(struct pci_dev *pci, | |||
1200 | than PAGE_SIZE */ | 1179 | than PAGE_SIZE */ |
1201 | /* Jump and write need an extra dword */ | 1180 | /* Jump and write need an extra dword */ |
1202 | instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; | 1181 | instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; |
1203 | instructions += 1; | 1182 | instructions += 4; |
1204 | 1183 | ||
1205 | rc = btcx_riscmem_alloc(pci, risc, instructions*12); | 1184 | rc = btcx_riscmem_alloc(pci, risc, instructions*12); |
1206 | if (rc < 0) | 1185 | if (rc < 0) |
@@ -1209,7 +1188,7 @@ int cx23885_risc_databuffer(struct pci_dev *pci, | |||
1209 | /* write risc instructions */ | 1188 | /* write risc instructions */ |
1210 | rp = risc->cpu; | 1189 | rp = risc->cpu; |
1211 | rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE, | 1190 | rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE, |
1212 | bpl, 0, lines, lpi); | 1191 | bpl, 0, lines, lpi, lpi == 0); |
1213 | 1192 | ||
1214 | /* save pointer to jmp instruction address */ | 1193 | /* save pointer to jmp instruction address */ |
1215 | risc->jmp = rp; | 1194 | risc->jmp = rp; |
@@ -1239,7 +1218,7 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
1239 | /* write and jump need and extra dword */ | 1218 | /* write and jump need and extra dword */ |
1240 | instructions = fields * (1 + ((bpl + padding) * lines) | 1219 | instructions = fields * (1 + ((bpl + padding) * lines) |
1241 | / PAGE_SIZE + lines); | 1220 | / PAGE_SIZE + lines); |
1242 | instructions += 2; | 1221 | instructions += 5; |
1243 | rc = btcx_riscmem_alloc(pci, risc, instructions*12); | 1222 | rc = btcx_riscmem_alloc(pci, risc, instructions*12); |
1244 | if (rc < 0) | 1223 | if (rc < 0) |
1245 | return rc; | 1224 | return rc; |
@@ -1250,11 +1229,11 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
1250 | * in the userland vbi payload */ | 1229 | * in the userland vbi payload */ |
1251 | if (UNSET != top_offset) | 1230 | if (UNSET != top_offset) |
1252 | rp = cx23885_risc_field(rp, sglist, top_offset, 6, | 1231 | rp = cx23885_risc_field(rp, sglist, top_offset, 6, |
1253 | bpl, padding, lines, 0); | 1232 | bpl, padding, lines, 0, true); |
1254 | 1233 | ||
1255 | if (UNSET != bottom_offset) | 1234 | if (UNSET != bottom_offset) |
1256 | rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x207, | 1235 | rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x207, |
1257 | bpl, padding, lines, 0); | 1236 | bpl, padding, lines, 0, UNSET == top_offset); |
1258 | 1237 | ||
1259 | 1238 | ||
1260 | 1239 | ||
@@ -1265,38 +1244,10 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
1265 | } | 1244 | } |
1266 | 1245 | ||
1267 | 1246 | ||
1268 | int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | 1247 | void cx23885_free_buffer(struct cx23885_dev *dev, struct cx23885_buffer *buf) |
1269 | u32 reg, u32 mask, u32 value) | ||
1270 | { | ||
1271 | __le32 *rp; | ||
1272 | int rc; | ||
1273 | |||
1274 | rc = btcx_riscmem_alloc(pci, risc, 4*16); | ||
1275 | if (rc < 0) | ||
1276 | return rc; | ||
1277 | |||
1278 | /* write risc instructions */ | ||
1279 | rp = risc->cpu; | ||
1280 | *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2); | ||
1281 | *(rp++) = cpu_to_le32(reg); | ||
1282 | *(rp++) = cpu_to_le32(value); | ||
1283 | *(rp++) = cpu_to_le32(mask); | ||
1284 | *(rp++) = cpu_to_le32(RISC_JUMP); | ||
1285 | *(rp++) = cpu_to_le32(risc->dma); | ||
1286 | *(rp++) = cpu_to_le32(0); /* bits 63-32 */ | ||
1287 | return 0; | ||
1288 | } | ||
1289 | |||
1290 | void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf) | ||
1291 | { | 1248 | { |
1292 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | ||
1293 | |||
1294 | BUG_ON(in_interrupt()); | 1249 | BUG_ON(in_interrupt()); |
1295 | videobuf_waiton(q, &buf->vb, 0, 0); | 1250 | btcx_riscmem_free(dev->pci, &buf->risc); |
1296 | videobuf_dma_unmap(q->dev, dma); | ||
1297 | videobuf_dma_free(dma); | ||
1298 | btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); | ||
1299 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | ||
1300 | } | 1251 | } |
1301 | 1252 | ||
1302 | static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) | 1253 | static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) |
@@ -1351,7 +1302,7 @@ static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) | |||
1351 | port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk)); | 1302 | port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk)); |
1352 | } | 1303 | } |
1353 | 1304 | ||
1354 | static int cx23885_start_dma(struct cx23885_tsport *port, | 1305 | int cx23885_start_dma(struct cx23885_tsport *port, |
1355 | struct cx23885_dmaqueue *q, | 1306 | struct cx23885_dmaqueue *q, |
1356 | struct cx23885_buffer *buf) | 1307 | struct cx23885_buffer *buf) |
1357 | { | 1308 | { |
@@ -1359,7 +1310,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, | |||
1359 | u32 reg; | 1310 | u32 reg; |
1360 | 1311 | ||
1361 | dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__, | 1312 | dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__, |
1362 | buf->vb.width, buf->vb.height, buf->vb.field); | 1313 | dev->width, dev->height, dev->field); |
1363 | 1314 | ||
1364 | /* Stop the fifo and risc engine for this port */ | 1315 | /* Stop the fifo and risc engine for this port */ |
1365 | cx_clear(port->reg_dma_ctl, port->dma_ctl_val); | 1316 | cx_clear(port->reg_dma_ctl, port->dma_ctl_val); |
@@ -1375,7 +1326,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, | |||
1375 | } | 1326 | } |
1376 | 1327 | ||
1377 | /* write TS length to chip */ | 1328 | /* write TS length to chip */ |
1378 | cx_write(port->reg_lngth, buf->vb.width); | 1329 | cx_write(port->reg_lngth, port->ts_packet_size); |
1379 | 1330 | ||
1380 | if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && | 1331 | if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && |
1381 | (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) { | 1332 | (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) { |
@@ -1404,7 +1355,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, | |||
1404 | /* NOTE: this is 2 (reserved) for portb, does it matter? */ | 1355 | /* NOTE: this is 2 (reserved) for portb, does it matter? */ |
1405 | /* reset counter to zero */ | 1356 | /* reset counter to zero */ |
1406 | cx_write(port->reg_gpcnt_ctl, 3); | 1357 | cx_write(port->reg_gpcnt_ctl, 3); |
1407 | q->count = 1; | 1358 | q->count = 0; |
1408 | 1359 | ||
1409 | /* Set VIDB pins to input */ | 1360 | /* Set VIDB pins to input */ |
1410 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { | 1361 | if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { |
@@ -1493,134 +1444,83 @@ static int cx23885_stop_dma(struct cx23885_tsport *port) | |||
1493 | return 0; | 1444 | return 0; |
1494 | } | 1445 | } |
1495 | 1446 | ||
1496 | int cx23885_restart_queue(struct cx23885_tsport *port, | ||
1497 | struct cx23885_dmaqueue *q) | ||
1498 | { | ||
1499 | struct cx23885_dev *dev = port->dev; | ||
1500 | struct cx23885_buffer *buf; | ||
1501 | |||
1502 | dprintk(5, "%s()\n", __func__); | ||
1503 | if (list_empty(&q->active)) { | ||
1504 | struct cx23885_buffer *prev; | ||
1505 | prev = NULL; | ||
1506 | |||
1507 | dprintk(5, "%s() queue is empty\n", __func__); | ||
1508 | |||
1509 | for (;;) { | ||
1510 | if (list_empty(&q->queued)) | ||
1511 | return 0; | ||
1512 | buf = list_entry(q->queued.next, struct cx23885_buffer, | ||
1513 | vb.queue); | ||
1514 | if (NULL == prev) { | ||
1515 | list_move_tail(&buf->vb.queue, &q->active); | ||
1516 | cx23885_start_dma(port, q, buf); | ||
1517 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
1518 | buf->count = q->count++; | ||
1519 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | ||
1520 | dprintk(5, "[%p/%d] restart_queue - f/active\n", | ||
1521 | buf, buf->vb.i); | ||
1522 | |||
1523 | } else if (prev->vb.width == buf->vb.width && | ||
1524 | prev->vb.height == buf->vb.height && | ||
1525 | prev->fmt == buf->fmt) { | ||
1526 | list_move_tail(&buf->vb.queue, &q->active); | ||
1527 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
1528 | buf->count = q->count++; | ||
1529 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | ||
1530 | /* 64 bit bits 63-32 */ | ||
1531 | prev->risc.jmp[2] = cpu_to_le32(0); | ||
1532 | dprintk(5, "[%p/%d] restart_queue - m/active\n", | ||
1533 | buf, buf->vb.i); | ||
1534 | } else { | ||
1535 | return 0; | ||
1536 | } | ||
1537 | prev = buf; | ||
1538 | } | ||
1539 | return 0; | ||
1540 | } | ||
1541 | |||
1542 | buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue); | ||
1543 | dprintk(2, "restart_queue [%p/%d]: restart dma\n", | ||
1544 | buf, buf->vb.i); | ||
1545 | cx23885_start_dma(port, q, buf); | ||
1546 | list_for_each_entry(buf, &q->active, vb.queue) | ||
1547 | buf->count = q->count++; | ||
1548 | mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); | ||
1549 | return 0; | ||
1550 | } | ||
1551 | |||
1552 | /* ------------------------------------------------------------------ */ | 1447 | /* ------------------------------------------------------------------ */ |
1553 | 1448 | ||
1554 | int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, | 1449 | int cx23885_buf_prepare(struct cx23885_buffer *buf, struct cx23885_tsport *port) |
1555 | struct cx23885_buffer *buf, enum v4l2_field field) | ||
1556 | { | 1450 | { |
1557 | struct cx23885_dev *dev = port->dev; | 1451 | struct cx23885_dev *dev = port->dev; |
1558 | int size = port->ts_packet_size * port->ts_packet_count; | 1452 | int size = port->ts_packet_size * port->ts_packet_count; |
1453 | struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0); | ||
1559 | int rc; | 1454 | int rc; |
1560 | 1455 | ||
1561 | dprintk(1, "%s: %p\n", __func__, buf); | 1456 | dprintk(1, "%s: %p\n", __func__, buf); |
1562 | if (0 != buf->vb.baddr && buf->vb.bsize < size) | 1457 | if (vb2_plane_size(&buf->vb, 0) < size) |
1563 | return -EINVAL; | 1458 | return -EINVAL; |
1459 | vb2_set_plane_payload(&buf->vb, 0, size); | ||
1564 | 1460 | ||
1565 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 1461 | rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); |
1566 | buf->vb.width = port->ts_packet_size; | 1462 | if (!rc) |
1567 | buf->vb.height = port->ts_packet_count; | 1463 | return -EIO; |
1568 | buf->vb.size = size; | ||
1569 | buf->vb.field = field /*V4L2_FIELD_TOP*/; | ||
1570 | |||
1571 | rc = videobuf_iolock(q, &buf->vb, NULL); | ||
1572 | if (0 != rc) | ||
1573 | goto fail; | ||
1574 | cx23885_risc_databuffer(dev->pci, &buf->risc, | ||
1575 | videobuf_to_dma(&buf->vb)->sglist, | ||
1576 | buf->vb.width, buf->vb.height, 0); | ||
1577 | } | ||
1578 | buf->vb.state = VIDEOBUF_PREPARED; | ||
1579 | return 0; | ||
1580 | 1464 | ||
1581 | fail: | 1465 | cx23885_risc_databuffer(dev->pci, &buf->risc, |
1582 | cx23885_free_buffer(q, buf); | 1466 | sgt->sgl, |
1583 | return rc; | 1467 | port->ts_packet_size, port->ts_packet_count, 0); |
1468 | return 0; | ||
1584 | } | 1469 | } |
1585 | 1470 | ||
1471 | /* | ||
1472 | * The risc program for each buffer works as follows: it starts with a simple | ||
1473 | * 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the | ||
1474 | * buffer follows and at the end we have a JUMP back to the start + 12 (skipping | ||
1475 | * the initial JUMP). | ||
1476 | * | ||
1477 | * This is the risc program of the first buffer to be queued if the active list | ||
1478 | * is empty and it just keeps DMAing this buffer without generating any | ||
1479 | * interrupts. | ||
1480 | * | ||
1481 | * If a new buffer is added then the initial JUMP in the code for that buffer | ||
1482 | * will generate an interrupt which signals that the previous buffer has been | ||
1483 | * DMAed successfully and that it can be returned to userspace. | ||
1484 | * | ||
1485 | * It also sets the final jump of the previous buffer to the start of the new | ||
1486 | * buffer, thus chaining the new buffer into the DMA chain. This is a single | ||
1487 | * atomic u32 write, so there is no race condition. | ||
1488 | * | ||
1489 | * The end-result of all this that you only get an interrupt when a buffer | ||
1490 | * is ready, so the control flow is very easy. | ||
1491 | */ | ||
1586 | void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) | 1492 | void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) |
1587 | { | 1493 | { |
1588 | struct cx23885_buffer *prev; | 1494 | struct cx23885_buffer *prev; |
1589 | struct cx23885_dev *dev = port->dev; | 1495 | struct cx23885_dev *dev = port->dev; |
1590 | struct cx23885_dmaqueue *cx88q = &port->mpegq; | 1496 | struct cx23885_dmaqueue *cx88q = &port->mpegq; |
1497 | unsigned long flags; | ||
1591 | 1498 | ||
1592 | /* add jump to stopper */ | 1499 | buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 12); |
1593 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); | 1500 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC); |
1594 | buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma); | 1501 | buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12); |
1595 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ | 1502 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ |
1596 | 1503 | ||
1504 | spin_lock_irqsave(&dev->slock, flags); | ||
1597 | if (list_empty(&cx88q->active)) { | 1505 | if (list_empty(&cx88q->active)) { |
1598 | dprintk(1, "queue is empty - first active\n"); | 1506 | list_add_tail(&buf->queue, &cx88q->active); |
1599 | list_add_tail(&buf->vb.queue, &cx88q->active); | ||
1600 | cx23885_start_dma(port, cx88q, buf); | ||
1601 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
1602 | buf->count = cx88q->count++; | ||
1603 | mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT); | ||
1604 | dprintk(1, "[%p/%d] %s - first active\n", | 1507 | dprintk(1, "[%p/%d] %s - first active\n", |
1605 | buf, buf->vb.i, __func__); | 1508 | buf, buf->vb.v4l2_buf.index, __func__); |
1606 | } else { | 1509 | } else { |
1607 | dprintk(1, "queue is not empty - append to active\n"); | 1510 | buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1); |
1608 | prev = list_entry(cx88q->active.prev, struct cx23885_buffer, | 1511 | prev = list_entry(cx88q->active.prev, struct cx23885_buffer, |
1609 | vb.queue); | 1512 | queue); |
1610 | list_add_tail(&buf->vb.queue, &cx88q->active); | 1513 | list_add_tail(&buf->queue, &cx88q->active); |
1611 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
1612 | buf->count = cx88q->count++; | ||
1613 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | 1514 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
1614 | prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ | ||
1615 | dprintk(1, "[%p/%d] %s - append to active\n", | 1515 | dprintk(1, "[%p/%d] %s - append to active\n", |
1616 | buf, buf->vb.i, __func__); | 1516 | buf, buf->vb.v4l2_buf.index, __func__); |
1617 | } | 1517 | } |
1518 | spin_unlock_irqrestore(&dev->slock, flags); | ||
1618 | } | 1519 | } |
1619 | 1520 | ||
1620 | /* ----------------------------------------------------------- */ | 1521 | /* ----------------------------------------------------------- */ |
1621 | 1522 | ||
1622 | static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, | 1523 | static void do_cancel_buffers(struct cx23885_tsport *port, char *reason) |
1623 | int restart) | ||
1624 | { | 1524 | { |
1625 | struct cx23885_dev *dev = port->dev; | 1525 | struct cx23885_dev *dev = port->dev; |
1626 | struct cx23885_dmaqueue *q = &port->mpegq; | 1526 | struct cx23885_dmaqueue *q = &port->mpegq; |
@@ -1630,16 +1530,11 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, | |||
1630 | spin_lock_irqsave(&port->slock, flags); | 1530 | spin_lock_irqsave(&port->slock, flags); |
1631 | while (!list_empty(&q->active)) { | 1531 | while (!list_empty(&q->active)) { |
1632 | buf = list_entry(q->active.next, struct cx23885_buffer, | 1532 | buf = list_entry(q->active.next, struct cx23885_buffer, |
1633 | vb.queue); | 1533 | queue); |
1634 | list_del(&buf->vb.queue); | 1534 | list_del(&buf->queue); |
1635 | buf->vb.state = VIDEOBUF_ERROR; | 1535 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); |
1636 | wake_up(&buf->vb.done); | ||
1637 | dprintk(1, "[%p/%d] %s - dma=0x%08lx\n", | 1536 | dprintk(1, "[%p/%d] %s - dma=0x%08lx\n", |
1638 | buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); | 1537 | buf, buf->vb.v4l2_buf.index, reason, (unsigned long)buf->risc.dma); |
1639 | } | ||
1640 | if (restart) { | ||
1641 | dprintk(1, "restarting queue\n"); | ||
1642 | cx23885_restart_queue(port, q); | ||
1643 | } | 1538 | } |
1644 | spin_unlock_irqrestore(&port->slock, flags); | 1539 | spin_unlock_irqrestore(&port->slock, flags); |
1645 | } | 1540 | } |
@@ -1647,27 +1542,10 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, | |||
1647 | void cx23885_cancel_buffers(struct cx23885_tsport *port) | 1542 | void cx23885_cancel_buffers(struct cx23885_tsport *port) |
1648 | { | 1543 | { |
1649 | struct cx23885_dev *dev = port->dev; | 1544 | struct cx23885_dev *dev = port->dev; |
1650 | struct cx23885_dmaqueue *q = &port->mpegq; | ||
1651 | |||
1652 | dprintk(1, "%s()\n", __func__); | ||
1653 | del_timer_sync(&q->timeout); | ||
1654 | cx23885_stop_dma(port); | ||
1655 | do_cancel_buffers(port, "cancel", 0); | ||
1656 | } | ||
1657 | |||
1658 | static void cx23885_timeout(unsigned long data) | ||
1659 | { | ||
1660 | struct cx23885_tsport *port = (struct cx23885_tsport *)data; | ||
1661 | struct cx23885_dev *dev = port->dev; | ||
1662 | 1545 | ||
1663 | dprintk(1, "%s()\n", __func__); | 1546 | dprintk(1, "%s()\n", __func__); |
1664 | |||
1665 | if (debug > 5) | ||
1666 | cx23885_sram_channel_dump(dev, | ||
1667 | &dev->sram_channels[port->sram_chno]); | ||
1668 | |||
1669 | cx23885_stop_dma(port); | 1547 | cx23885_stop_dma(port); |
1670 | do_cancel_buffers(port, "timeout", 1); | 1548 | do_cancel_buffers(port, "cancel"); |
1671 | } | 1549 | } |
1672 | 1550 | ||
1673 | int cx23885_irq_417(struct cx23885_dev *dev, u32 status) | 1551 | int cx23885_irq_417(struct cx23885_dev *dev, u32 status) |
@@ -1717,11 +1595,6 @@ int cx23885_irq_417(struct cx23885_dev *dev, u32 status) | |||
1717 | spin_lock(&port->slock); | 1595 | spin_lock(&port->slock); |
1718 | cx23885_wakeup(port, &port->mpegq, count); | 1596 | cx23885_wakeup(port, &port->mpegq, count); |
1719 | spin_unlock(&port->slock); | 1597 | spin_unlock(&port->slock); |
1720 | } else if (status & VID_B_MSK_RISCI2) { | ||
1721 | dprintk(7, " VID_B_MSK_RISCI2\n"); | ||
1722 | spin_lock(&port->slock); | ||
1723 | cx23885_restart_queue(port, &port->mpegq); | ||
1724 | spin_unlock(&port->slock); | ||
1725 | } | 1598 | } |
1726 | if (status) { | 1599 | if (status) { |
1727 | cx_write(port->reg_ts_int_stat, status); | 1600 | cx_write(port->reg_ts_int_stat, status); |
@@ -1773,14 +1646,6 @@ static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) | |||
1773 | cx23885_wakeup(port, &port->mpegq, count); | 1646 | cx23885_wakeup(port, &port->mpegq, count); |
1774 | spin_unlock(&port->slock); | 1647 | spin_unlock(&port->slock); |
1775 | 1648 | ||
1776 | } else if (status & VID_BC_MSK_RISCI2) { | ||
1777 | |||
1778 | dprintk(7, " (RISCI2 0x%08x)\n", VID_BC_MSK_RISCI2); | ||
1779 | |||
1780 | spin_lock(&port->slock); | ||
1781 | cx23885_restart_queue(port, &port->mpegq); | ||
1782 | spin_unlock(&port->slock); | ||
1783 | |||
1784 | } | 1649 | } |
1785 | if (status) { | 1650 | if (status) { |
1786 | cx_write(port->reg_ts_int_stat, status); | 1651 | cx_write(port->reg_ts_int_stat, status); |
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index d71d59f6c6d6..332e6facc095 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c | |||
@@ -87,59 +87,95 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | |||
87 | 87 | ||
88 | /* ------------------------------------------------------------------ */ | 88 | /* ------------------------------------------------------------------ */ |
89 | 89 | ||
90 | static int dvb_buf_setup(struct videobuf_queue *q, | 90 | static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, |
91 | unsigned int *count, unsigned int *size) | 91 | unsigned int *num_buffers, unsigned int *num_planes, |
92 | unsigned int sizes[], void *alloc_ctxs[]) | ||
92 | { | 93 | { |
93 | struct cx23885_tsport *port = q->priv_data; | 94 | struct cx23885_tsport *port = q->drv_priv; |
94 | 95 | ||
95 | port->ts_packet_size = 188 * 4; | 96 | port->ts_packet_size = 188 * 4; |
96 | port->ts_packet_count = 32; | 97 | port->ts_packet_count = 32; |
97 | 98 | *num_planes = 1; | |
98 | *size = port->ts_packet_size * port->ts_packet_count; | 99 | sizes[0] = port->ts_packet_size * port->ts_packet_count; |
99 | *count = 32; | 100 | *num_buffers = 32; |
100 | return 0; | 101 | return 0; |
101 | } | 102 | } |
102 | 103 | ||
103 | static int dvb_buf_prepare(struct videobuf_queue *q, | 104 | |
104 | struct videobuf_buffer *vb, enum v4l2_field field) | 105 | static int buffer_prepare(struct vb2_buffer *vb) |
105 | { | 106 | { |
106 | struct cx23885_tsport *port = q->priv_data; | 107 | struct cx23885_tsport *port = vb->vb2_queue->drv_priv; |
107 | return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field); | 108 | struct cx23885_buffer *buf = |
109 | container_of(vb, struct cx23885_buffer, vb); | ||
110 | |||
111 | return cx23885_buf_prepare(buf, port); | ||
108 | } | 112 | } |
109 | 113 | ||
110 | static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | 114 | static void buffer_finish(struct vb2_buffer *vb) |
111 | { | 115 | { |
112 | struct cx23885_tsport *port = q->priv_data; | 116 | struct cx23885_tsport *port = vb->vb2_queue->drv_priv; |
113 | cx23885_buf_queue(port, (struct cx23885_buffer *)vb); | 117 | struct cx23885_dev *dev = port->dev; |
118 | struct cx23885_buffer *buf = container_of(vb, | ||
119 | struct cx23885_buffer, vb); | ||
120 | struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); | ||
121 | |||
122 | cx23885_free_buffer(dev, buf); | ||
123 | |||
124 | dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); | ||
114 | } | 125 | } |
115 | 126 | ||
116 | static void dvb_buf_release(struct videobuf_queue *q, | 127 | static void buffer_queue(struct vb2_buffer *vb) |
117 | struct videobuf_buffer *vb) | ||
118 | { | 128 | { |
119 | cx23885_free_buffer(q, (struct cx23885_buffer *)vb); | 129 | struct cx23885_tsport *port = vb->vb2_queue->drv_priv; |
130 | struct cx23885_buffer *buf = container_of(vb, | ||
131 | struct cx23885_buffer, vb); | ||
132 | |||
133 | cx23885_buf_queue(port, buf); | ||
120 | } | 134 | } |
121 | 135 | ||
122 | static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open) | 136 | static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open) |
123 | { | 137 | { |
124 | struct videobuf_dvb_frontends *f; | 138 | struct vb2_dvb_frontends *f; |
125 | struct videobuf_dvb_frontend *fe; | 139 | struct vb2_dvb_frontend *fe; |
126 | 140 | ||
127 | f = &port->frontends; | 141 | f = &port->frontends; |
128 | 142 | ||
129 | if (f->gate <= 1) /* undefined or fe0 */ | 143 | if (f->gate <= 1) /* undefined or fe0 */ |
130 | fe = videobuf_dvb_get_frontend(f, 1); | 144 | fe = vb2_dvb_get_frontend(f, 1); |
131 | else | 145 | else |
132 | fe = videobuf_dvb_get_frontend(f, f->gate); | 146 | fe = vb2_dvb_get_frontend(f, f->gate); |
133 | 147 | ||
134 | if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) | 148 | if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) |
135 | fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open); | 149 | fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open); |
136 | } | 150 | } |
137 | 151 | ||
138 | static struct videobuf_queue_ops dvb_qops = { | 152 | static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count) |
139 | .buf_setup = dvb_buf_setup, | 153 | { |
140 | .buf_prepare = dvb_buf_prepare, | 154 | struct cx23885_tsport *port = q->drv_priv; |
141 | .buf_queue = dvb_buf_queue, | 155 | struct cx23885_dmaqueue *dmaq = &port->mpegq; |
142 | .buf_release = dvb_buf_release, | 156 | struct cx23885_buffer *buf = list_entry(dmaq->active.next, |
157 | struct cx23885_buffer, queue); | ||
158 | |||
159 | cx23885_start_dma(port, dmaq, buf); | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static void cx23885_stop_streaming(struct vb2_queue *q) | ||
164 | { | ||
165 | struct cx23885_tsport *port = q->drv_priv; | ||
166 | |||
167 | cx23885_cancel_buffers(port); | ||
168 | } | ||
169 | |||
170 | static struct vb2_ops dvb_qops = { | ||
171 | .queue_setup = queue_setup, | ||
172 | .buf_prepare = buffer_prepare, | ||
173 | .buf_finish = buffer_finish, | ||
174 | .buf_queue = buffer_queue, | ||
175 | .wait_prepare = vb2_ops_wait_prepare, | ||
176 | .wait_finish = vb2_ops_wait_finish, | ||
177 | .start_streaming = cx23885_start_streaming, | ||
178 | .stop_streaming = cx23885_stop_streaming, | ||
143 | }; | 179 | }; |
144 | 180 | ||
145 | static struct s5h1409_config hauppauge_generic_config = { | 181 | static struct s5h1409_config hauppauge_generic_config = { |
@@ -859,16 +895,16 @@ static int dvb_register(struct cx23885_tsport *port) | |||
859 | struct dib7000p_ops dib7000p_ops; | 895 | struct dib7000p_ops dib7000p_ops; |
860 | struct cx23885_dev *dev = port->dev; | 896 | struct cx23885_dev *dev = port->dev; |
861 | struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; | 897 | struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; |
862 | struct videobuf_dvb_frontend *fe0, *fe1 = NULL; | 898 | struct vb2_dvb_frontend *fe0, *fe1 = NULL; |
863 | int mfe_shared = 0; /* bus not shared by default */ | 899 | int mfe_shared = 0; /* bus not shared by default */ |
864 | int ret; | 900 | int ret; |
865 | 901 | ||
866 | /* Get the first frontend */ | 902 | /* Get the first frontend */ |
867 | fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); | 903 | fe0 = vb2_dvb_get_frontend(&port->frontends, 1); |
868 | if (!fe0) | 904 | if (!fe0) |
869 | return -EINVAL; | 905 | return -EINVAL; |
870 | 906 | ||
871 | /* init struct videobuf_dvb */ | 907 | /* init struct vb2_dvb */ |
872 | fe0->dvb.name = dev->name; | 908 | fe0->dvb.name = dev->name; |
873 | 909 | ||
874 | /* multi-frontend gate control is undefined or defaults to fe0 */ | 910 | /* multi-frontend gate control is undefined or defaults to fe0 */ |
@@ -1388,7 +1424,7 @@ static int dvb_register(struct cx23885_tsport *port) | |||
1388 | fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend); | 1424 | fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend); |
1389 | } | 1425 | } |
1390 | /* MFE frontend 2 */ | 1426 | /* MFE frontend 2 */ |
1391 | fe1 = videobuf_dvb_get_frontend(&port->frontends, 2); | 1427 | fe1 = vb2_dvb_get_frontend(&port->frontends, 2); |
1392 | if (fe1 == NULL) | 1428 | if (fe1 == NULL) |
1393 | goto frontend_detach; | 1429 | goto frontend_detach; |
1394 | /* DVB-C init */ | 1430 | /* DVB-C init */ |
@@ -1528,7 +1564,7 @@ static int dvb_register(struct cx23885_tsport *port) | |||
1528 | fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); | 1564 | fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); |
1529 | 1565 | ||
1530 | /* register everything */ | 1566 | /* register everything */ |
1531 | ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, | 1567 | ret = vb2_dvb_register_bus(&port->frontends, THIS_MODULE, port, |
1532 | &dev->pci->dev, adapter_nr, mfe_shared); | 1568 | &dev->pci->dev, adapter_nr, mfe_shared); |
1533 | if (ret) | 1569 | if (ret) |
1534 | goto frontend_detach; | 1570 | goto frontend_detach; |
@@ -1577,14 +1613,14 @@ static int dvb_register(struct cx23885_tsport *port) | |||
1577 | 1613 | ||
1578 | frontend_detach: | 1614 | frontend_detach: |
1579 | port->gate_ctrl = NULL; | 1615 | port->gate_ctrl = NULL; |
1580 | videobuf_dvb_dealloc_frontends(&port->frontends); | 1616 | vb2_dvb_dealloc_frontends(&port->frontends); |
1581 | return -EINVAL; | 1617 | return -EINVAL; |
1582 | } | 1618 | } |
1583 | 1619 | ||
1584 | int cx23885_dvb_register(struct cx23885_tsport *port) | 1620 | int cx23885_dvb_register(struct cx23885_tsport *port) |
1585 | { | 1621 | { |
1586 | 1622 | ||
1587 | struct videobuf_dvb_frontend *fe0; | 1623 | struct vb2_dvb_frontend *fe0; |
1588 | struct cx23885_dev *dev = port->dev; | 1624 | struct cx23885_dev *dev = port->dev; |
1589 | int err, i; | 1625 | int err, i; |
1590 | 1626 | ||
@@ -1601,13 +1637,15 @@ int cx23885_dvb_register(struct cx23885_tsport *port) | |||
1601 | port->num_frontends); | 1637 | port->num_frontends); |
1602 | 1638 | ||
1603 | for (i = 1; i <= port->num_frontends; i++) { | 1639 | for (i = 1; i <= port->num_frontends; i++) { |
1604 | if (videobuf_dvb_alloc_frontend( | 1640 | struct vb2_queue *q; |
1641 | |||
1642 | if (vb2_dvb_alloc_frontend( | ||
1605 | &port->frontends, i) == NULL) { | 1643 | &port->frontends, i) == NULL) { |
1606 | printk(KERN_ERR "%s() failed to alloc\n", __func__); | 1644 | printk(KERN_ERR "%s() failed to alloc\n", __func__); |
1607 | return -ENOMEM; | 1645 | return -ENOMEM; |
1608 | } | 1646 | } |
1609 | 1647 | ||
1610 | fe0 = videobuf_dvb_get_frontend(&port->frontends, i); | 1648 | fe0 = vb2_dvb_get_frontend(&port->frontends, i); |
1611 | if (!fe0) | 1649 | if (!fe0) |
1612 | err = -EINVAL; | 1650 | err = -EINVAL; |
1613 | 1651 | ||
@@ -1623,10 +1661,21 @@ int cx23885_dvb_register(struct cx23885_tsport *port) | |||
1623 | /* dvb stuff */ | 1661 | /* dvb stuff */ |
1624 | /* We have to init the queue for each frontend on a port. */ | 1662 | /* We have to init the queue for each frontend on a port. */ |
1625 | printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); | 1663 | printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); |
1626 | videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, | 1664 | q = &fe0->dvb.dvbq; |
1627 | &dev->pci->dev, &port->slock, | 1665 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1628 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, | 1666 | q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; |
1629 | sizeof(struct cx23885_buffer), port, NULL); | 1667 | q->gfp_flags = GFP_DMA32; |
1668 | q->min_buffers_needed = 2; | ||
1669 | q->drv_priv = port; | ||
1670 | q->buf_struct_size = sizeof(struct cx23885_buffer); | ||
1671 | q->ops = &dvb_qops; | ||
1672 | q->mem_ops = &vb2_dma_sg_memops; | ||
1673 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
1674 | q->lock = &dev->lock; | ||
1675 | |||
1676 | err = vb2_queue_init(q); | ||
1677 | if (err < 0) | ||
1678 | return err; | ||
1630 | } | 1679 | } |
1631 | err = dvb_register(port); | 1680 | err = dvb_register(port); |
1632 | if (err != 0) | 1681 | if (err != 0) |
@@ -1638,7 +1687,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port) | |||
1638 | 1687 | ||
1639 | int cx23885_dvb_unregister(struct cx23885_tsport *port) | 1688 | int cx23885_dvb_unregister(struct cx23885_tsport *port) |
1640 | { | 1689 | { |
1641 | struct videobuf_dvb_frontend *fe0; | 1690 | struct vb2_dvb_frontend *fe0; |
1642 | 1691 | ||
1643 | /* FIXME: in an error condition where the we have | 1692 | /* FIXME: in an error condition where the we have |
1644 | * an expected number of frontends (attach problem) | 1693 | * an expected number of frontends (attach problem) |
@@ -1647,9 +1696,9 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port) | |||
1647 | * This comment only applies to future boards IF they | 1696 | * This comment only applies to future boards IF they |
1648 | * implement MFE support. | 1697 | * implement MFE support. |
1649 | */ | 1698 | */ |
1650 | fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); | 1699 | fe0 = vb2_dvb_get_frontend(&port->frontends, 1); |
1651 | if (fe0 && fe0->dvb.frontend) | 1700 | if (fe0 && fe0->dvb.frontend) |
1652 | videobuf_dvb_unregister_bus(&port->frontends); | 1701 | vb2_dvb_unregister_bus(&port->frontends); |
1653 | 1702 | ||
1654 | switch (port->dev->board) { | 1703 | switch (port->dev->board) { |
1655 | case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: | 1704 | case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: |
diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c index 23790fadc6d5..67b71f9b41f4 100644 --- a/drivers/media/pci/cx23885/cx23885-vbi.c +++ b/drivers/media/pci/cx23885/cx23885-vbi.c | |||
@@ -38,9 +38,8 @@ MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]"); | |||
38 | /* ------------------------------------------------------------------ */ | 38 | /* ------------------------------------------------------------------ */ |
39 | 39 | ||
40 | #define VBI_LINE_LENGTH 1440 | 40 | #define VBI_LINE_LENGTH 1440 |
41 | #define NTSC_VBI_START_LINE 10 /* line 10 - 21 */ | 41 | #define VBI_NTSC_LINE_COUNT 12 |
42 | #define NTSC_VBI_END_LINE 21 | 42 | #define VBI_PAL_LINE_COUNT 18 |
43 | #define NTSC_VBI_LINES (NTSC_VBI_END_LINE - NTSC_VBI_START_LINE + 1) | ||
44 | 43 | ||
45 | 44 | ||
46 | int cx23885_vbi_fmt(struct file *file, void *priv, | 45 | int cx23885_vbi_fmt(struct file *file, void *priv, |
@@ -48,22 +47,23 @@ int cx23885_vbi_fmt(struct file *file, void *priv, | |||
48 | { | 47 | { |
49 | struct cx23885_dev *dev = video_drvdata(file); | 48 | struct cx23885_dev *dev = video_drvdata(file); |
50 | 49 | ||
50 | f->fmt.vbi.sampling_rate = 27000000; | ||
51 | f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; | ||
52 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
53 | f->fmt.vbi.offset = 0; | ||
54 | f->fmt.vbi.flags = 0; | ||
51 | if (dev->tvnorm & V4L2_STD_525_60) { | 55 | if (dev->tvnorm & V4L2_STD_525_60) { |
52 | /* ntsc */ | 56 | /* ntsc */ |
53 | f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; | ||
54 | f->fmt.vbi.sampling_rate = 27000000; | ||
55 | f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
56 | f->fmt.vbi.offset = 0; | ||
57 | f->fmt.vbi.flags = 0; | ||
58 | f->fmt.vbi.start[0] = 10; | 57 | f->fmt.vbi.start[0] = 10; |
59 | f->fmt.vbi.count[0] = 17; | 58 | f->fmt.vbi.start[1] = 272; |
60 | f->fmt.vbi.start[1] = 263 + 10 + 1; | 59 | f->fmt.vbi.count[0] = VBI_NTSC_LINE_COUNT; |
61 | f->fmt.vbi.count[1] = 17; | 60 | f->fmt.vbi.count[1] = VBI_NTSC_LINE_COUNT; |
62 | } else if (dev->tvnorm & V4L2_STD_625_50) { | 61 | } else if (dev->tvnorm & V4L2_STD_625_50) { |
63 | /* pal */ | 62 | /* pal */ |
64 | f->fmt.vbi.sampling_rate = 35468950; | 63 | f->fmt.vbi.start[0] = 6; |
65 | f->fmt.vbi.start[0] = 7 - 1; | 64 | f->fmt.vbi.start[1] = 318; |
66 | f->fmt.vbi.start[1] = 319 - 1; | 65 | f->fmt.vbi.count[0] = VBI_PAL_LINE_COUNT; |
66 | f->fmt.vbi.count[1] = VBI_PAL_LINE_COUNT; | ||
67 | } | 67 | } |
68 | 68 | ||
69 | return 0; | 69 | return 0; |
@@ -89,15 +89,6 @@ int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status) | |||
89 | handled++; | 89 | handled++; |
90 | } | 90 | } |
91 | 91 | ||
92 | if (status & VID_BC_MSK_VBI_RISCI2) { | ||
93 | dprintk(1, "%s() VID_BC_MSK_VBI_RISCI2\n", __func__); | ||
94 | dprintk(2, "stopper vbi\n"); | ||
95 | spin_lock(&dev->slock); | ||
96 | cx23885_restart_vbi_queue(dev, &dev->vbiq); | ||
97 | spin_unlock(&dev->slock); | ||
98 | handled++; | ||
99 | } | ||
100 | |||
101 | return handled; | 92 | return handled; |
102 | } | 93 | } |
103 | 94 | ||
@@ -109,13 +100,13 @@ static int cx23885_start_vbi_dma(struct cx23885_dev *dev, | |||
109 | 100 | ||
110 | /* setup fifo + format */ | 101 | /* setup fifo + format */ |
111 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02], | 102 | cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02], |
112 | buf->vb.width, buf->risc.dma); | 103 | VBI_LINE_LENGTH, buf->risc.dma); |
113 | 104 | ||
114 | /* reset counter */ | 105 | /* reset counter */ |
115 | cx_write(VID_A_GPCNT_CTL, 3); | 106 | cx_write(VID_A_GPCNT_CTL, 3); |
116 | cx_write(VID_A_VBI_CTRL, 3); | 107 | cx_write(VID_A_VBI_CTRL, 3); |
117 | cx_write(VBI_A_GPCNT_CTL, 3); | 108 | cx_write(VBI_A_GPCNT_CTL, 3); |
118 | q->count = 1; | 109 | q->count = 0; |
119 | 110 | ||
120 | /* enable irq */ | 111 | /* enable irq */ |
121 | cx23885_irq_add_enable(dev, 0x01); | 112 | cx23885_irq_add_enable(dev, 0x01); |
@@ -128,163 +119,153 @@ static int cx23885_start_vbi_dma(struct cx23885_dev *dev, | |||
128 | return 0; | 119 | return 0; |
129 | } | 120 | } |
130 | 121 | ||
122 | /* ------------------------------------------------------------------ */ | ||
131 | 123 | ||
132 | int cx23885_restart_vbi_queue(struct cx23885_dev *dev, | 124 | static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, |
133 | struct cx23885_dmaqueue *q) | 125 | unsigned int *num_buffers, unsigned int *num_planes, |
126 | unsigned int sizes[], void *alloc_ctxs[]) | ||
134 | { | 127 | { |
135 | struct cx23885_buffer *buf; | 128 | struct cx23885_dev *dev = q->drv_priv; |
136 | struct list_head *item; | 129 | unsigned lines = VBI_PAL_LINE_COUNT; |
137 | 130 | ||
138 | if (list_empty(&q->active)) | 131 | if (dev->tvnorm & V4L2_STD_525_60) |
139 | return 0; | 132 | lines = VBI_NTSC_LINE_COUNT; |
140 | 133 | *num_planes = 1; | |
141 | buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue); | 134 | sizes[0] = lines * VBI_LINE_LENGTH * 2; |
142 | dprintk(2, "restart_queue [%p/%d]: restart dma\n", | ||
143 | buf, buf->vb.i); | ||
144 | cx23885_start_vbi_dma(dev, q, buf); | ||
145 | list_for_each(item, &q->active) { | ||
146 | buf = list_entry(item, struct cx23885_buffer, vb.queue); | ||
147 | buf->count = q->count++; | ||
148 | } | ||
149 | mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30)); | ||
150 | return 0; | 135 | return 0; |
151 | } | 136 | } |
152 | 137 | ||
153 | void cx23885_vbi_timeout(unsigned long data) | 138 | static int buffer_prepare(struct vb2_buffer *vb) |
154 | { | 139 | { |
155 | struct cx23885_dev *dev = (struct cx23885_dev *)data; | 140 | struct cx23885_dev *dev = vb->vb2_queue->drv_priv; |
156 | struct cx23885_dmaqueue *q = &dev->vbiq; | 141 | struct cx23885_buffer *buf = container_of(vb, |
157 | struct cx23885_buffer *buf; | 142 | struct cx23885_buffer, vb); |
158 | unsigned long flags; | 143 | struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); |
144 | unsigned lines = VBI_PAL_LINE_COUNT; | ||
145 | int ret; | ||
159 | 146 | ||
160 | /* Stop the VBI engine */ | 147 | if (dev->tvnorm & V4L2_STD_525_60) |
161 | cx_clear(VID_A_DMA_CTL, 0x22); | 148 | lines = VBI_NTSC_LINE_COUNT; |
162 | 149 | ||
163 | spin_lock_irqsave(&dev->slock, flags); | 150 | if (vb2_plane_size(vb, 0) < lines * VBI_LINE_LENGTH * 2) |
164 | while (!list_empty(&q->active)) { | 151 | return -EINVAL; |
165 | buf = list_entry(q->active.next, struct cx23885_buffer, | 152 | vb2_set_plane_payload(vb, 0, lines * VBI_LINE_LENGTH * 2); |
166 | vb.queue); | ||
167 | list_del(&buf->vb.queue); | ||
168 | buf->vb.state = VIDEOBUF_ERROR; | ||
169 | wake_up(&buf->vb.done); | ||
170 | printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->name, | ||
171 | buf, buf->vb.i, (unsigned long)buf->risc.dma); | ||
172 | } | ||
173 | cx23885_restart_vbi_queue(dev, q); | ||
174 | spin_unlock_irqrestore(&dev->slock, flags); | ||
175 | } | ||
176 | 153 | ||
177 | /* ------------------------------------------------------------------ */ | 154 | ret = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); |
178 | #define VBI_LINE_LENGTH 1440 | 155 | if (!ret) |
179 | #define VBI_LINE_COUNT 17 | 156 | return -EIO; |
180 | 157 | ||
181 | static int | 158 | cx23885_risc_vbibuffer(dev->pci, &buf->risc, |
182 | vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) | 159 | sgt->sgl, |
183 | { | 160 | 0, VBI_LINE_LENGTH * lines, |
184 | *size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; | 161 | VBI_LINE_LENGTH, 0, |
185 | if (0 == *count) | 162 | lines); |
186 | *count = vbibufs; | ||
187 | if (*count < 2) | ||
188 | *count = 2; | ||
189 | if (*count > 32) | ||
190 | *count = 32; | ||
191 | return 0; | 163 | return 0; |
192 | } | 164 | } |
193 | 165 | ||
194 | static int | 166 | static void buffer_finish(struct vb2_buffer *vb) |
195 | vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | ||
196 | enum v4l2_field field) | ||
197 | { | 167 | { |
198 | struct cx23885_fh *fh = q->priv_data; | 168 | struct cx23885_dev *dev = vb->vb2_queue->drv_priv; |
199 | struct cx23885_dev *dev = fh->q_dev; | ||
200 | struct cx23885_buffer *buf = container_of(vb, | 169 | struct cx23885_buffer *buf = container_of(vb, |
201 | struct cx23885_buffer, vb); | 170 | struct cx23885_buffer, vb); |
202 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | 171 | struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); |
203 | unsigned int size; | ||
204 | int rc; | ||
205 | |||
206 | size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; | ||
207 | if (0 != buf->vb.baddr && buf->vb.bsize < size) | ||
208 | return -EINVAL; | ||
209 | 172 | ||
210 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 173 | cx23885_free_buffer(vb->vb2_queue->drv_priv, buf); |
211 | buf->vb.width = VBI_LINE_LENGTH; | ||
212 | buf->vb.height = VBI_LINE_COUNT; | ||
213 | buf->vb.size = size; | ||
214 | buf->vb.field = V4L2_FIELD_SEQ_TB; | ||
215 | |||
216 | rc = videobuf_iolock(q, &buf->vb, NULL); | ||
217 | if (0 != rc) | ||
218 | goto fail; | ||
219 | cx23885_risc_vbibuffer(dev->pci, &buf->risc, | ||
220 | dma->sglist, | ||
221 | 0, buf->vb.width * buf->vb.height, | ||
222 | buf->vb.width, 0, | ||
223 | buf->vb.height); | ||
224 | } | ||
225 | buf->vb.state = VIDEOBUF_PREPARED; | ||
226 | return 0; | ||
227 | 174 | ||
228 | fail: | 175 | dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); |
229 | cx23885_free_buffer(q, buf); | ||
230 | return rc; | ||
231 | } | 176 | } |
232 | 177 | ||
233 | static void | 178 | /* |
234 | vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | 179 | * The risc program for each buffer works as follows: it starts with a simple |
180 | * 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the | ||
181 | * buffer follows and at the end we have a JUMP back to the start + 12 (skipping | ||
182 | * the initial JUMP). | ||
183 | * | ||
184 | * This is the risc program of the first buffer to be queued if the active list | ||
185 | * is empty and it just keeps DMAing this buffer without generating any | ||
186 | * interrupts. | ||
187 | * | ||
188 | * If a new buffer is added then the initial JUMP in the code for that buffer | ||
189 | * will generate an interrupt which signals that the previous buffer has been | ||
190 | * DMAed successfully and that it can be returned to userspace. | ||
191 | * | ||
192 | * It also sets the final jump of the previous buffer to the start of the new | ||
193 | * buffer, thus chaining the new buffer into the DMA chain. This is a single | ||
194 | * atomic u32 write, so there is no race condition. | ||
195 | * | ||
196 | * The end-result of all this that you only get an interrupt when a buffer | ||
197 | * is ready, so the control flow is very easy. | ||
198 | */ | ||
199 | static void buffer_queue(struct vb2_buffer *vb) | ||
235 | { | 200 | { |
236 | struct cx23885_buffer *buf = | 201 | struct cx23885_dev *dev = vb->vb2_queue->drv_priv; |
237 | container_of(vb, struct cx23885_buffer, vb); | 202 | struct cx23885_buffer *buf = container_of(vb, struct cx23885_buffer, vb); |
238 | struct cx23885_buffer *prev; | 203 | struct cx23885_buffer *prev; |
239 | struct cx23885_fh *fh = vq->priv_data; | 204 | struct cx23885_dmaqueue *q = &dev->vbiq; |
240 | struct cx23885_dev *dev = fh->q_dev; | 205 | unsigned long flags; |
241 | struct cx23885_dmaqueue *q = &dev->vbiq; | 206 | |
242 | 207 | buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 12); | |
243 | /* add jump to stopper */ | 208 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC); |
244 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); | 209 | buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12); |
245 | buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); | ||
246 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ | 210 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ |
247 | 211 | ||
248 | if (list_empty(&q->active)) { | 212 | if (list_empty(&q->active)) { |
249 | list_add_tail(&buf->vb.queue, &q->active); | 213 | spin_lock_irqsave(&dev->slock, flags); |
250 | cx23885_start_vbi_dma(dev, q, buf); | 214 | list_add_tail(&buf->queue, &q->active); |
251 | buf->vb.state = VIDEOBUF_ACTIVE; | 215 | spin_unlock_irqrestore(&dev->slock, flags); |
252 | buf->count = q->count++; | ||
253 | mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30)); | ||
254 | dprintk(2, "[%p/%d] vbi_queue - first active\n", | 216 | dprintk(2, "[%p/%d] vbi_queue - first active\n", |
255 | buf, buf->vb.i); | 217 | buf, buf->vb.v4l2_buf.index); |
256 | 218 | ||
257 | } else { | 219 | } else { |
220 | buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1); | ||
258 | prev = list_entry(q->active.prev, struct cx23885_buffer, | 221 | prev = list_entry(q->active.prev, struct cx23885_buffer, |
259 | vb.queue); | 222 | queue); |
260 | list_add_tail(&buf->vb.queue, &q->active); | 223 | spin_lock_irqsave(&dev->slock, flags); |
261 | buf->vb.state = VIDEOBUF_ACTIVE; | 224 | list_add_tail(&buf->queue, &q->active); |
262 | buf->count = q->count++; | 225 | spin_unlock_irqrestore(&dev->slock, flags); |
263 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | 226 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
264 | prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63-32 */ | ||
265 | dprintk(2, "[%p/%d] buffer_queue - append to active\n", | 227 | dprintk(2, "[%p/%d] buffer_queue - append to active\n", |
266 | buf, buf->vb.i); | 228 | buf, buf->vb.v4l2_buf.index); |
267 | } | 229 | } |
268 | } | 230 | } |
269 | 231 | ||
270 | static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | 232 | static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count) |
271 | { | 233 | { |
272 | struct cx23885_buffer *buf = | 234 | struct cx23885_dev *dev = q->drv_priv; |
273 | container_of(vb, struct cx23885_buffer, vb); | 235 | struct cx23885_dmaqueue *dmaq = &dev->vbiq; |
236 | struct cx23885_buffer *buf = list_entry(dmaq->active.next, | ||
237 | struct cx23885_buffer, queue); | ||
274 | 238 | ||
275 | cx23885_free_buffer(q, buf); | 239 | cx23885_start_vbi_dma(dev, dmaq, buf); |
240 | return 0; | ||
276 | } | 241 | } |
277 | 242 | ||
278 | struct videobuf_queue_ops cx23885_vbi_qops = { | 243 | static void cx23885_stop_streaming(struct vb2_queue *q) |
279 | .buf_setup = vbi_setup, | 244 | { |
280 | .buf_prepare = vbi_prepare, | 245 | struct cx23885_dev *dev = q->drv_priv; |
281 | .buf_queue = vbi_queue, | 246 | struct cx23885_dmaqueue *dmaq = &dev->vbiq; |
282 | .buf_release = vbi_release, | 247 | unsigned long flags; |
283 | }; | ||
284 | 248 | ||
285 | /* ------------------------------------------------------------------ */ | 249 | cx_clear(VID_A_DMA_CTL, 0x22); /* FIFO and RISC enable */ |
286 | /* | 250 | spin_lock_irqsave(&dev->slock, flags); |
287 | * Local variables: | 251 | while (!list_empty(&dmaq->active)) { |
288 | * c-basic-offset: 8 | 252 | struct cx23885_buffer *buf = list_entry(dmaq->active.next, |
289 | * End: | 253 | struct cx23885_buffer, queue); |
290 | */ | 254 | |
255 | list_del(&buf->queue); | ||
256 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); | ||
257 | } | ||
258 | spin_unlock_irqrestore(&dev->slock, flags); | ||
259 | } | ||
260 | |||
261 | |||
262 | struct vb2_ops cx23885_vbi_qops = { | ||
263 | .queue_setup = queue_setup, | ||
264 | .buf_prepare = buffer_prepare, | ||
265 | .buf_finish = buffer_finish, | ||
266 | .buf_queue = buffer_queue, | ||
267 | .wait_prepare = vb2_ops_wait_prepare, | ||
268 | .wait_finish = vb2_ops_wait_finish, | ||
269 | .start_streaming = cx23885_start_streaming, | ||
270 | .stop_streaming = cx23885_stop_streaming, | ||
271 | }; | ||
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 9cd8cf48334b..c6921d4bb7dd 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c | |||
@@ -98,34 +98,18 @@ void cx23885_video_wakeup(struct cx23885_dev *dev, | |||
98 | struct cx23885_dmaqueue *q, u32 count) | 98 | struct cx23885_dmaqueue *q, u32 count) |
99 | { | 99 | { |
100 | struct cx23885_buffer *buf; | 100 | struct cx23885_buffer *buf; |
101 | int bc; | 101 | |
102 | |||
103 | for (bc = 0;; bc++) { | ||
104 | if (list_empty(&q->active)) | ||
105 | break; | ||
106 | buf = list_entry(q->active.next, | ||
107 | struct cx23885_buffer, vb.queue); | ||
108 | |||
109 | /* count comes from the hw and is is 16bit wide -- | ||
110 | * this trick handles wrap-arounds correctly for | ||
111 | * up to 32767 buffers in flight... */ | ||
112 | if ((s16) (count - buf->count) < 0) | ||
113 | break; | ||
114 | |||
115 | v4l2_get_timestamp(&buf->vb.ts); | ||
116 | dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i, | ||
117 | count, buf->count); | ||
118 | buf->vb.state = VIDEOBUF_DONE; | ||
119 | list_del(&buf->vb.queue); | ||
120 | wake_up(&buf->vb.done); | ||
121 | } | ||
122 | if (list_empty(&q->active)) | 102 | if (list_empty(&q->active)) |
123 | del_timer(&q->timeout); | 103 | return; |
124 | else | 104 | buf = list_entry(q->active.next, |
125 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | 105 | struct cx23885_buffer, queue); |
126 | if (bc != 1) | 106 | |
127 | printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", | 107 | buf->vb.v4l2_buf.sequence = q->count++; |
128 | __func__, bc); | 108 | v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); |
109 | dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.v4l2_buf.index, | ||
110 | count, q->count); | ||
111 | list_del(&buf->queue); | ||
112 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); | ||
129 | } | 113 | } |
130 | 114 | ||
131 | int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) | 115 | int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) |
@@ -163,50 +147,6 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, | |||
163 | return vfd; | 147 | return vfd; |
164 | } | 148 | } |
165 | 149 | ||
166 | /* ------------------------------------------------------------------- */ | ||
167 | /* resource management */ | ||
168 | |||
169 | static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh, | ||
170 | unsigned int bit) | ||
171 | { | ||
172 | dprintk(1, "%s()\n", __func__); | ||
173 | if (fh->resources & bit) | ||
174 | /* have it already allocated */ | ||
175 | return 1; | ||
176 | |||
177 | /* is it free? */ | ||
178 | if (dev->resources & bit) { | ||
179 | /* no, someone else uses it */ | ||
180 | return 0; | ||
181 | } | ||
182 | /* it's free, grab it */ | ||
183 | fh->resources |= bit; | ||
184 | dev->resources |= bit; | ||
185 | dprintk(1, "res: get %d\n", bit); | ||
186 | return 1; | ||
187 | } | ||
188 | |||
189 | static int res_check(struct cx23885_fh *fh, unsigned int bit) | ||
190 | { | ||
191 | return fh->resources & bit; | ||
192 | } | ||
193 | |||
194 | static int res_locked(struct cx23885_dev *dev, unsigned int bit) | ||
195 | { | ||
196 | return dev->resources & bit; | ||
197 | } | ||
198 | |||
199 | static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh, | ||
200 | unsigned int bits) | ||
201 | { | ||
202 | BUG_ON((fh->resources & bits) != bits); | ||
203 | dprintk(1, "%s()\n", __func__); | ||
204 | |||
205 | fh->resources &= ~bits; | ||
206 | dev->resources &= ~bits; | ||
207 | dprintk(1, "res: put %d\n", bits); | ||
208 | } | ||
209 | |||
210 | int cx23885_flatiron_write(struct cx23885_dev *dev, u8 reg, u8 data) | 150 | int cx23885_flatiron_write(struct cx23885_dev *dev, u8 reg, u8 data) |
211 | { | 151 | { |
212 | /* 8 bit registers, 8 bit values */ | 152 | /* 8 bit registers, 8 bit values */ |
@@ -356,7 +296,7 @@ static int cx23885_start_video_dma(struct cx23885_dev *dev, | |||
356 | 296 | ||
357 | /* reset counter */ | 297 | /* reset counter */ |
358 | cx_write(VID_A_GPCNT_CTL, 3); | 298 | cx_write(VID_A_GPCNT_CTL, 3); |
359 | q->count = 1; | 299 | q->count = 0; |
360 | 300 | ||
361 | /* enable irq */ | 301 | /* enable irq */ |
362 | cx23885_irq_add_enable(dev, 0x01); | 302 | cx23885_irq_add_enable(dev, 0x01); |
@@ -369,444 +309,206 @@ static int cx23885_start_video_dma(struct cx23885_dev *dev, | |||
369 | return 0; | 309 | return 0; |
370 | } | 310 | } |
371 | 311 | ||
372 | 312 | static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, | |
373 | static int cx23885_restart_video_queue(struct cx23885_dev *dev, | 313 | unsigned int *num_buffers, unsigned int *num_planes, |
374 | struct cx23885_dmaqueue *q) | 314 | unsigned int sizes[], void *alloc_ctxs[]) |
375 | { | 315 | { |
376 | struct cx23885_buffer *buf, *prev; | 316 | struct cx23885_dev *dev = q->drv_priv; |
377 | struct list_head *item; | ||
378 | dprintk(1, "%s()\n", __func__); | ||
379 | |||
380 | if (!list_empty(&q->active)) { | ||
381 | buf = list_entry(q->active.next, struct cx23885_buffer, | ||
382 | vb.queue); | ||
383 | dprintk(2, "restart_queue [%p/%d]: restart dma\n", | ||
384 | buf, buf->vb.i); | ||
385 | cx23885_start_video_dma(dev, q, buf); | ||
386 | list_for_each(item, &q->active) { | ||
387 | buf = list_entry(item, struct cx23885_buffer, | ||
388 | vb.queue); | ||
389 | buf->count = q->count++; | ||
390 | } | ||
391 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | ||
392 | return 0; | ||
393 | } | ||
394 | 317 | ||
395 | prev = NULL; | 318 | *num_planes = 1; |
396 | for (;;) { | 319 | sizes[0] = (dev->fmt->depth * dev->width * dev->height) >> 3; |
397 | if (list_empty(&q->queued)) | ||
398 | return 0; | ||
399 | buf = list_entry(q->queued.next, struct cx23885_buffer, | ||
400 | vb.queue); | ||
401 | if (NULL == prev) { | ||
402 | list_move_tail(&buf->vb.queue, &q->active); | ||
403 | cx23885_start_video_dma(dev, q, buf); | ||
404 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
405 | buf->count = q->count++; | ||
406 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | ||
407 | dprintk(2, "[%p/%d] restart_queue - first active\n", | ||
408 | buf, buf->vb.i); | ||
409 | |||
410 | } else if (prev->vb.width == buf->vb.width && | ||
411 | prev->vb.height == buf->vb.height && | ||
412 | prev->fmt == buf->fmt) { | ||
413 | list_move_tail(&buf->vb.queue, &q->active); | ||
414 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
415 | buf->count = q->count++; | ||
416 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | ||
417 | prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */ | ||
418 | dprintk(2, "[%p/%d] restart_queue - move to active\n", | ||
419 | buf, buf->vb.i); | ||
420 | } else { | ||
421 | return 0; | ||
422 | } | ||
423 | prev = buf; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | static int buffer_setup(struct videobuf_queue *q, unsigned int *count, | ||
428 | unsigned int *size) | ||
429 | { | ||
430 | struct cx23885_fh *fh = q->priv_data; | ||
431 | struct cx23885_dev *dev = fh->q_dev; | ||
432 | |||
433 | *size = (dev->fmt->depth * dev->width * dev->height) >> 3; | ||
434 | if (0 == *count) | ||
435 | *count = 32; | ||
436 | if (*size * *count > vid_limit * 1024 * 1024) | ||
437 | *count = (vid_limit * 1024 * 1024) / *size; | ||
438 | return 0; | 320 | return 0; |
439 | } | 321 | } |
440 | 322 | ||
441 | static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | 323 | static int buffer_prepare(struct vb2_buffer *vb) |
442 | enum v4l2_field field) | ||
443 | { | 324 | { |
444 | struct cx23885_fh *fh = q->priv_data; | 325 | struct cx23885_dev *dev = vb->vb2_queue->drv_priv; |
445 | struct cx23885_dev *dev = fh->q_dev; | ||
446 | struct cx23885_buffer *buf = | 326 | struct cx23885_buffer *buf = |
447 | container_of(vb, struct cx23885_buffer, vb); | 327 | container_of(vb, struct cx23885_buffer, vb); |
448 | int rc, init_buffer = 0; | ||
449 | u32 line0_offset, line1_offset; | 328 | u32 line0_offset, line1_offset; |
450 | struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); | 329 | struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); |
451 | int field_tff; | 330 | int field_tff; |
331 | int ret; | ||
452 | 332 | ||
453 | if (WARN_ON(NULL == dev->fmt)) | 333 | buf->bpl = (dev->width * dev->fmt->depth) >> 3; |
454 | return -EINVAL; | ||
455 | 334 | ||
456 | if (dev->width < 48 || dev->width > norm_maxw(dev->tvnorm) || | 335 | if (vb2_plane_size(vb, 0) < dev->height * buf->bpl) |
457 | dev->height < 32 || dev->height > norm_maxh(dev->tvnorm)) | ||
458 | return -EINVAL; | ||
459 | buf->vb.size = (dev->width * dev->height * dev->fmt->depth) >> 3; | ||
460 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | ||
461 | return -EINVAL; | 336 | return -EINVAL; |
337 | vb2_set_plane_payload(vb, 0, dev->height * buf->bpl); | ||
462 | 338 | ||
463 | if (buf->fmt != dev->fmt || | 339 | ret = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); |
464 | buf->vb.width != dev->width || | 340 | if (!ret) |
465 | buf->vb.height != dev->height || | 341 | return -EIO; |
466 | buf->vb.field != field) { | ||
467 | buf->fmt = dev->fmt; | ||
468 | buf->vb.width = dev->width; | ||
469 | buf->vb.height = dev->height; | ||
470 | buf->vb.field = field; | ||
471 | init_buffer = 1; | ||
472 | } | ||
473 | 342 | ||
474 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 343 | switch (dev->field) { |
475 | init_buffer = 1; | 344 | case V4L2_FIELD_TOP: |
476 | rc = videobuf_iolock(q, &buf->vb, NULL); | 345 | cx23885_risc_buffer(dev->pci, &buf->risc, |
477 | if (0 != rc) | 346 | sgt->sgl, 0, UNSET, |
478 | goto fail; | 347 | buf->bpl, 0, dev->height); |
479 | } | 348 | break; |
349 | case V4L2_FIELD_BOTTOM: | ||
350 | cx23885_risc_buffer(dev->pci, &buf->risc, | ||
351 | sgt->sgl, UNSET, 0, | ||
352 | buf->bpl, 0, dev->height); | ||
353 | break; | ||
354 | case V4L2_FIELD_INTERLACED: | ||
355 | if (dev->tvnorm & V4L2_STD_NTSC) | ||
356 | /* NTSC or */ | ||
357 | field_tff = 1; | ||
358 | else | ||
359 | field_tff = 0; | ||
360 | |||
361 | if (cx23885_boards[dev->board].force_bff) | ||
362 | /* PAL / SECAM OR 888 in NTSC MODE */ | ||
363 | field_tff = 0; | ||
480 | 364 | ||
481 | if (init_buffer) { | 365 | if (field_tff) { |
482 | buf->bpl = buf->vb.width * buf->fmt->depth >> 3; | 366 | /* cx25840 transmits NTSC bottom field first */ |
483 | switch (buf->vb.field) { | 367 | dprintk(1, "%s() Creating TFF/NTSC risc\n", |
484 | case V4L2_FIELD_TOP: | ||
485 | cx23885_risc_buffer(dev->pci, &buf->risc, | ||
486 | dma->sglist, 0, UNSET, | ||
487 | buf->bpl, 0, buf->vb.height); | ||
488 | break; | ||
489 | case V4L2_FIELD_BOTTOM: | ||
490 | cx23885_risc_buffer(dev->pci, &buf->risc, | ||
491 | dma->sglist, UNSET, 0, | ||
492 | buf->bpl, 0, buf->vb.height); | ||
493 | break; | ||
494 | case V4L2_FIELD_INTERLACED: | ||
495 | if (dev->tvnorm & V4L2_STD_NTSC) | ||
496 | /* NTSC or */ | ||
497 | field_tff = 1; | ||
498 | else | ||
499 | field_tff = 0; | ||
500 | |||
501 | if (cx23885_boards[dev->board].force_bff) | ||
502 | /* PAL / SECAM OR 888 in NTSC MODE */ | ||
503 | field_tff = 0; | ||
504 | |||
505 | if (field_tff) { | ||
506 | /* cx25840 transmits NTSC bottom field first */ | ||
507 | dprintk(1, "%s() Creating TFF/NTSC risc\n", | ||
508 | __func__); | 368 | __func__); |
509 | line0_offset = buf->bpl; | 369 | line0_offset = buf->bpl; |
510 | line1_offset = 0; | 370 | line1_offset = 0; |
511 | } else { | 371 | } else { |
512 | /* All other formats are top field first */ | 372 | /* All other formats are top field first */ |
513 | dprintk(1, "%s() Creating BFF/PAL/SECAM risc\n", | 373 | dprintk(1, "%s() Creating BFF/PAL/SECAM risc\n", |
514 | __func__); | 374 | __func__); |
515 | line0_offset = 0; | 375 | line0_offset = 0; |
516 | line1_offset = buf->bpl; | 376 | line1_offset = buf->bpl; |
517 | } | ||
518 | cx23885_risc_buffer(dev->pci, &buf->risc, | ||
519 | dma->sglist, line0_offset, | ||
520 | line1_offset, | ||
521 | buf->bpl, buf->bpl, | ||
522 | buf->vb.height >> 1); | ||
523 | break; | ||
524 | case V4L2_FIELD_SEQ_TB: | ||
525 | cx23885_risc_buffer(dev->pci, &buf->risc, | ||
526 | dma->sglist, | ||
527 | 0, buf->bpl * (buf->vb.height >> 1), | ||
528 | buf->bpl, 0, | ||
529 | buf->vb.height >> 1); | ||
530 | break; | ||
531 | case V4L2_FIELD_SEQ_BT: | ||
532 | cx23885_risc_buffer(dev->pci, &buf->risc, | ||
533 | dma->sglist, | ||
534 | buf->bpl * (buf->vb.height >> 1), 0, | ||
535 | buf->bpl, 0, | ||
536 | buf->vb.height >> 1); | ||
537 | break; | ||
538 | default: | ||
539 | BUG(); | ||
540 | } | 377 | } |
378 | cx23885_risc_buffer(dev->pci, &buf->risc, | ||
379 | sgt->sgl, line0_offset, | ||
380 | line1_offset, | ||
381 | buf->bpl, buf->bpl, | ||
382 | dev->height >> 1); | ||
383 | break; | ||
384 | case V4L2_FIELD_SEQ_TB: | ||
385 | cx23885_risc_buffer(dev->pci, &buf->risc, | ||
386 | sgt->sgl, | ||
387 | 0, buf->bpl * (dev->height >> 1), | ||
388 | buf->bpl, 0, | ||
389 | dev->height >> 1); | ||
390 | break; | ||
391 | case V4L2_FIELD_SEQ_BT: | ||
392 | cx23885_risc_buffer(dev->pci, &buf->risc, | ||
393 | sgt->sgl, | ||
394 | buf->bpl * (dev->height >> 1), 0, | ||
395 | buf->bpl, 0, | ||
396 | dev->height >> 1); | ||
397 | break; | ||
398 | default: | ||
399 | BUG(); | ||
541 | } | 400 | } |
542 | dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", | 401 | dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", |
543 | buf, buf->vb.i, | 402 | buf, buf->vb.v4l2_buf.index, |
544 | dev->width, dev->height, dev->fmt->depth, dev->fmt->name, | 403 | dev->width, dev->height, dev->fmt->depth, dev->fmt->name, |
545 | (unsigned long)buf->risc.dma); | 404 | (unsigned long)buf->risc.dma); |
546 | |||
547 | buf->vb.state = VIDEOBUF_PREPARED; | ||
548 | return 0; | 405 | return 0; |
406 | } | ||
549 | 407 | ||
550 | fail: | 408 | static void buffer_finish(struct vb2_buffer *vb) |
551 | cx23885_free_buffer(q, buf); | 409 | { |
552 | return rc; | 410 | struct cx23885_dev *dev = vb->vb2_queue->drv_priv; |
411 | struct cx23885_buffer *buf = container_of(vb, | ||
412 | struct cx23885_buffer, vb); | ||
413 | struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); | ||
414 | |||
415 | cx23885_free_buffer(vb->vb2_queue->drv_priv, buf); | ||
416 | |||
417 | dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); | ||
553 | } | 418 | } |
554 | 419 | ||
555 | static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | 420 | /* |
421 | * The risc program for each buffer works as follows: it starts with a simple | ||
422 | * 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the | ||
423 | * buffer follows and at the end we have a JUMP back to the start + 12 (skipping | ||
424 | * the initial JUMP). | ||
425 | * | ||
426 | * This is the risc program of the first buffer to be queued if the active list | ||
427 | * is empty and it just keeps DMAing this buffer without generating any | ||
428 | * interrupts. | ||
429 | * | ||
430 | * If a new buffer is added then the initial JUMP in the code for that buffer | ||
431 | * will generate an interrupt which signals that the previous buffer has been | ||
432 | * DMAed successfully and that it can be returned to userspace. | ||
433 | * | ||
434 | * It also sets the final jump of the previous buffer to the start of the new | ||
435 | * buffer, thus chaining the new buffer into the DMA chain. This is a single | ||
436 | * atomic u32 write, so there is no race condition. | ||
437 | * | ||
438 | * The end-result of all this that you only get an interrupt when a buffer | ||
439 | * is ready, so the control flow is very easy. | ||
440 | */ | ||
441 | static void buffer_queue(struct vb2_buffer *vb) | ||
556 | { | 442 | { |
443 | struct cx23885_dev *dev = vb->vb2_queue->drv_priv; | ||
557 | struct cx23885_buffer *buf = container_of(vb, | 444 | struct cx23885_buffer *buf = container_of(vb, |
558 | struct cx23885_buffer, vb); | 445 | struct cx23885_buffer, vb); |
559 | struct cx23885_buffer *prev; | 446 | struct cx23885_buffer *prev; |
560 | struct cx23885_fh *fh = vq->priv_data; | ||
561 | struct cx23885_dev *dev = fh->q_dev; | ||
562 | struct cx23885_dmaqueue *q = &dev->vidq; | 447 | struct cx23885_dmaqueue *q = &dev->vidq; |
448 | unsigned long flags; | ||
563 | 449 | ||
564 | /* add jump to stopper */ | 450 | /* add jump to start */ |
565 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); | 451 | buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 12); |
566 | buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); | 452 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC); |
453 | buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12); | ||
567 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ | 454 | buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ |
568 | 455 | ||
569 | if (!list_empty(&q->queued)) { | 456 | spin_lock_irqsave(&dev->slock, flags); |
570 | list_add_tail(&buf->vb.queue, &q->queued); | 457 | if (list_empty(&q->active)) { |
571 | buf->vb.state = VIDEOBUF_QUEUED; | 458 | list_add_tail(&buf->queue, &q->active); |
572 | dprintk(2, "[%p/%d] buffer_queue - append to queued\n", | ||
573 | buf, buf->vb.i); | ||
574 | |||
575 | } else if (list_empty(&q->active)) { | ||
576 | list_add_tail(&buf->vb.queue, &q->active); | ||
577 | cx23885_start_video_dma(dev, q, buf); | ||
578 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
579 | buf->count = q->count++; | ||
580 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | ||
581 | dprintk(2, "[%p/%d] buffer_queue - first active\n", | 459 | dprintk(2, "[%p/%d] buffer_queue - first active\n", |
582 | buf, buf->vb.i); | 460 | buf, buf->vb.v4l2_buf.index); |
583 | |||
584 | } else { | 461 | } else { |
462 | buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1); | ||
585 | prev = list_entry(q->active.prev, struct cx23885_buffer, | 463 | prev = list_entry(q->active.prev, struct cx23885_buffer, |
586 | vb.queue); | 464 | queue); |
587 | if (prev->vb.width == buf->vb.width && | 465 | list_add_tail(&buf->queue, &q->active); |
588 | prev->vb.height == buf->vb.height && | 466 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
589 | prev->fmt == buf->fmt) { | 467 | dprintk(2, "[%p/%d] buffer_queue - append to active\n", |
590 | list_add_tail(&buf->vb.queue, &q->active); | 468 | buf, buf->vb.v4l2_buf.index); |
591 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
592 | buf->count = q->count++; | ||
593 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | ||
594 | /* 64 bit bits 63-32 */ | ||
595 | prev->risc.jmp[2] = cpu_to_le32(0); | ||
596 | dprintk(2, "[%p/%d] buffer_queue - append to active\n", | ||
597 | buf, buf->vb.i); | ||
598 | |||
599 | } else { | ||
600 | list_add_tail(&buf->vb.queue, &q->queued); | ||
601 | buf->vb.state = VIDEOBUF_QUEUED; | ||
602 | dprintk(2, "[%p/%d] buffer_queue - first queued\n", | ||
603 | buf, buf->vb.i); | ||
604 | } | ||
605 | } | ||
606 | } | ||
607 | |||
608 | static void buffer_release(struct videobuf_queue *q, | ||
609 | struct videobuf_buffer *vb) | ||
610 | { | ||
611 | struct cx23885_buffer *buf = container_of(vb, | ||
612 | struct cx23885_buffer, vb); | ||
613 | |||
614 | cx23885_free_buffer(q, buf); | ||
615 | } | ||
616 | |||
617 | static struct videobuf_queue_ops cx23885_video_qops = { | ||
618 | .buf_setup = buffer_setup, | ||
619 | .buf_prepare = buffer_prepare, | ||
620 | .buf_queue = buffer_queue, | ||
621 | .buf_release = buffer_release, | ||
622 | }; | ||
623 | |||
624 | static struct videobuf_queue *get_queue(struct file *file) | ||
625 | { | ||
626 | struct video_device *vdev = video_devdata(file); | ||
627 | struct cx23885_fh *fh = file->private_data; | ||
628 | |||
629 | switch (vdev->vfl_type) { | ||
630 | case VFL_TYPE_GRABBER: | ||
631 | return &fh->vidq; | ||
632 | case VFL_TYPE_VBI: | ||
633 | return &fh->vbiq; | ||
634 | default: | ||
635 | WARN_ON(1); | ||
636 | return NULL; | ||
637 | } | ||
638 | } | ||
639 | |||
640 | static int get_resource(u32 type) | ||
641 | { | ||
642 | switch (type) { | ||
643 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
644 | return RESOURCE_VIDEO; | ||
645 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
646 | return RESOURCE_VBI; | ||
647 | default: | ||
648 | WARN_ON(1); | ||
649 | return 0; | ||
650 | } | 469 | } |
470 | spin_unlock_irqrestore(&dev->slock, flags); | ||
651 | } | 471 | } |
652 | 472 | ||
653 | static int video_open(struct file *file) | 473 | static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count) |
654 | { | 474 | { |
655 | struct video_device *vdev = video_devdata(file); | 475 | struct cx23885_dev *dev = q->drv_priv; |
656 | struct cx23885_dev *dev = video_drvdata(file); | 476 | struct cx23885_dmaqueue *dmaq = &dev->vidq; |
657 | struct cx23885_fh *fh; | 477 | struct cx23885_buffer *buf = list_entry(dmaq->active.next, |
658 | 478 | struct cx23885_buffer, queue); | |
659 | dprintk(1, "open dev=%s\n", | ||
660 | video_device_node_name(vdev)); | ||
661 | |||
662 | /* allocate + initialize per filehandle data */ | ||
663 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | ||
664 | if (NULL == fh) | ||
665 | return -ENOMEM; | ||
666 | |||
667 | v4l2_fh_init(&fh->fh, vdev); | ||
668 | file->private_data = &fh->fh; | ||
669 | fh->q_dev = dev; | ||
670 | |||
671 | videobuf_queue_sg_init(&fh->vidq, &cx23885_video_qops, | ||
672 | &dev->pci->dev, &dev->slock, | ||
673 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
674 | V4L2_FIELD_INTERLACED, | ||
675 | sizeof(struct cx23885_buffer), | ||
676 | fh, NULL); | ||
677 | |||
678 | videobuf_queue_sg_init(&fh->vbiq, &cx23885_vbi_qops, | ||
679 | &dev->pci->dev, &dev->slock, | ||
680 | V4L2_BUF_TYPE_VBI_CAPTURE, | ||
681 | V4L2_FIELD_SEQ_TB, | ||
682 | sizeof(struct cx23885_buffer), | ||
683 | fh, NULL); | ||
684 | |||
685 | v4l2_fh_add(&fh->fh); | ||
686 | |||
687 | dprintk(1, "post videobuf_queue_init()\n"); | ||
688 | 479 | ||
480 | cx23885_start_video_dma(dev, dmaq, buf); | ||
689 | return 0; | 481 | return 0; |
690 | } | 482 | } |
691 | 483 | ||
692 | static ssize_t video_read(struct file *file, char __user *data, | 484 | static void cx23885_stop_streaming(struct vb2_queue *q) |
693 | size_t count, loff_t *ppos) | ||
694 | { | 485 | { |
695 | struct video_device *vdev = video_devdata(file); | 486 | struct cx23885_dev *dev = q->drv_priv; |
696 | struct cx23885_dev *dev = video_drvdata(file); | 487 | struct cx23885_dmaqueue *dmaq = &dev->vidq; |
697 | struct cx23885_fh *fh = file->private_data; | 488 | unsigned long flags; |
698 | |||
699 | switch (vdev->vfl_type) { | ||
700 | case VFL_TYPE_GRABBER: | ||
701 | if (res_locked(dev, RESOURCE_VIDEO)) | ||
702 | return -EBUSY; | ||
703 | return videobuf_read_one(&fh->vidq, data, count, ppos, | ||
704 | file->f_flags & O_NONBLOCK); | ||
705 | case VFL_TYPE_VBI: | ||
706 | if (!res_get(dev, fh, RESOURCE_VBI)) | ||
707 | return -EBUSY; | ||
708 | return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1, | ||
709 | file->f_flags & O_NONBLOCK); | ||
710 | default: | ||
711 | return -EINVAL; | ||
712 | } | ||
713 | } | ||
714 | |||
715 | static unsigned int video_poll(struct file *file, | ||
716 | struct poll_table_struct *wait) | ||
717 | { | ||
718 | struct video_device *vdev = video_devdata(file); | ||
719 | struct cx23885_dev *dev = video_drvdata(file); | ||
720 | struct cx23885_fh *fh = file->private_data; | ||
721 | struct cx23885_buffer *buf; | ||
722 | unsigned long req_events = poll_requested_events(wait); | ||
723 | unsigned int rc = 0; | ||
724 | |||
725 | if (v4l2_event_pending(&fh->fh)) | ||
726 | rc = POLLPRI; | ||
727 | else | ||
728 | poll_wait(file, &fh->fh.wait, wait); | ||
729 | if (!(req_events & (POLLIN | POLLRDNORM))) | ||
730 | return rc; | ||
731 | |||
732 | if (vdev->vfl_type == VFL_TYPE_VBI) { | ||
733 | if (!res_get(dev, fh, RESOURCE_VBI)) | ||
734 | return rc | POLLERR; | ||
735 | return rc | videobuf_poll_stream(file, &fh->vbiq, wait); | ||
736 | } | ||
737 | |||
738 | mutex_lock(&fh->vidq.vb_lock); | ||
739 | if (res_check(fh, RESOURCE_VIDEO)) { | ||
740 | /* streaming capture */ | ||
741 | if (list_empty(&fh->vidq.stream)) | ||
742 | goto done; | ||
743 | buf = list_entry(fh->vidq.stream.next, | ||
744 | struct cx23885_buffer, vb.stream); | ||
745 | } else { | ||
746 | /* read() capture */ | ||
747 | buf = (struct cx23885_buffer *)fh->vidq.read_buf; | ||
748 | if (NULL == buf) | ||
749 | goto done; | ||
750 | } | ||
751 | poll_wait(file, &buf->vb.done, wait); | ||
752 | if (buf->vb.state == VIDEOBUF_DONE || | ||
753 | buf->vb.state == VIDEOBUF_ERROR) | ||
754 | rc |= POLLIN | POLLRDNORM; | ||
755 | done: | ||
756 | mutex_unlock(&fh->vidq.vb_lock); | ||
757 | return rc; | ||
758 | } | ||
759 | |||
760 | static int video_release(struct file *file) | ||
761 | { | ||
762 | struct cx23885_dev *dev = video_drvdata(file); | ||
763 | struct cx23885_fh *fh = file->private_data; | ||
764 | |||
765 | /* turn off overlay */ | ||
766 | if (res_check(fh, RESOURCE_OVERLAY)) { | ||
767 | /* FIXME */ | ||
768 | res_free(dev, fh, RESOURCE_OVERLAY); | ||
769 | } | ||
770 | 489 | ||
771 | /* stop video capture */ | 490 | cx_clear(VID_A_DMA_CTL, 0x11); |
772 | if (res_check(fh, RESOURCE_VIDEO)) { | 491 | spin_lock_irqsave(&dev->slock, flags); |
773 | videobuf_queue_cancel(&fh->vidq); | 492 | while (!list_empty(&dmaq->active)) { |
774 | res_free(dev, fh, RESOURCE_VIDEO); | 493 | struct cx23885_buffer *buf = list_entry(dmaq->active.next, |
775 | } | 494 | struct cx23885_buffer, queue); |
776 | if (fh->vidq.read_buf) { | ||
777 | buffer_release(&fh->vidq, fh->vidq.read_buf); | ||
778 | kfree(fh->vidq.read_buf); | ||
779 | } | ||
780 | 495 | ||
781 | /* stop vbi capture */ | 496 | list_del(&buf->queue); |
782 | if (res_check(fh, RESOURCE_VBI)) { | 497 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); |
783 | if (fh->vbiq.streaming) | ||
784 | videobuf_streamoff(&fh->vbiq); | ||
785 | if (fh->vbiq.reading) | ||
786 | videobuf_read_stop(&fh->vbiq); | ||
787 | res_free(dev, fh, RESOURCE_VBI); | ||
788 | } | 498 | } |
789 | 499 | spin_unlock_irqrestore(&dev->slock, flags); | |
790 | videobuf_mmap_free(&fh->vidq); | ||
791 | videobuf_mmap_free(&fh->vbiq); | ||
792 | |||
793 | v4l2_fh_del(&fh->fh); | ||
794 | v4l2_fh_exit(&fh->fh); | ||
795 | file->private_data = NULL; | ||
796 | kfree(fh); | ||
797 | |||
798 | /* We are not putting the tuner to sleep here on exit, because | ||
799 | * we want to use the mpeg encoder in another session to capture | ||
800 | * tuner video. Closing this will result in no video to the encoder. | ||
801 | */ | ||
802 | |||
803 | return 0; | ||
804 | } | 500 | } |
805 | 501 | ||
806 | static int video_mmap(struct file *file, struct vm_area_struct *vma) | 502 | static struct vb2_ops cx23885_video_qops = { |
807 | { | 503 | .queue_setup = queue_setup, |
808 | return videobuf_mmap_mapper(get_queue(file), vma); | 504 | .buf_prepare = buffer_prepare, |
809 | } | 505 | .buf_finish = buffer_finish, |
506 | .buf_queue = buffer_queue, | ||
507 | .wait_prepare = vb2_ops_wait_prepare, | ||
508 | .wait_finish = vb2_ops_wait_finish, | ||
509 | .start_streaming = cx23885_start_streaming, | ||
510 | .stop_streaming = cx23885_stop_streaming, | ||
511 | }; | ||
810 | 512 | ||
811 | /* ------------------------------------------------------------------ */ | 513 | /* ------------------------------------------------------------------ */ |
812 | /* VIDEO IOCTLS */ | 514 | /* VIDEO IOCTLS */ |
@@ -815,11 +517,10 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
815 | struct v4l2_format *f) | 517 | struct v4l2_format *f) |
816 | { | 518 | { |
817 | struct cx23885_dev *dev = video_drvdata(file); | 519 | struct cx23885_dev *dev = video_drvdata(file); |
818 | struct cx23885_fh *fh = priv; | ||
819 | 520 | ||
820 | f->fmt.pix.width = dev->width; | 521 | f->fmt.pix.width = dev->width; |
821 | f->fmt.pix.height = dev->height; | 522 | f->fmt.pix.height = dev->height; |
822 | f->fmt.pix.field = fh->vidq.field; | 523 | f->fmt.pix.field = dev->field; |
823 | f->fmt.pix.pixelformat = dev->fmt->fourcc; | 524 | f->fmt.pix.pixelformat = dev->fmt->fourcc; |
824 | f->fmt.pix.bytesperline = | 525 | f->fmt.pix.bytesperline = |
825 | (f->fmt.pix.width * dev->fmt->depth) >> 3; | 526 | (f->fmt.pix.width * dev->fmt->depth) >> 3; |
@@ -880,7 +581,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
880 | struct v4l2_format *f) | 581 | struct v4l2_format *f) |
881 | { | 582 | { |
882 | struct cx23885_dev *dev = video_drvdata(file); | 583 | struct cx23885_dev *dev = video_drvdata(file); |
883 | struct cx23885_fh *fh = priv; | ||
884 | struct v4l2_mbus_framefmt mbus_fmt; | 584 | struct v4l2_mbus_framefmt mbus_fmt; |
885 | int err; | 585 | int err; |
886 | 586 | ||
@@ -892,9 +592,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
892 | dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 592 | dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
893 | dev->width = f->fmt.pix.width; | 593 | dev->width = f->fmt.pix.width; |
894 | dev->height = f->fmt.pix.height; | 594 | dev->height = f->fmt.pix.height; |
895 | fh->vidq.field = f->fmt.pix.field; | 595 | dev->field = f->fmt.pix.field; |
896 | dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, | 596 | dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, |
897 | dev->width, dev->height, fh->vidq.field); | 597 | dev->width, dev->height, dev->field); |
898 | v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); | 598 | v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); |
899 | call_all(dev, video, s_mbus_fmt, &mbus_fmt); | 599 | call_all(dev, video, s_mbus_fmt, &mbus_fmt); |
900 | v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); | 600 | v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); |
@@ -936,82 +636,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | |||
936 | return 0; | 636 | return 0; |
937 | } | 637 | } |
938 | 638 | ||
939 | static int vidioc_reqbufs(struct file *file, void *priv, | ||
940 | struct v4l2_requestbuffers *p) | ||
941 | { | ||
942 | return videobuf_reqbufs(get_queue(file), p); | ||
943 | } | ||
944 | |||
945 | static int vidioc_querybuf(struct file *file, void *priv, | ||
946 | struct v4l2_buffer *p) | ||
947 | { | ||
948 | return videobuf_querybuf(get_queue(file), p); | ||
949 | } | ||
950 | |||
951 | static int vidioc_qbuf(struct file *file, void *priv, | ||
952 | struct v4l2_buffer *p) | ||
953 | { | ||
954 | return videobuf_qbuf(get_queue(file), p); | ||
955 | } | ||
956 | |||
957 | static int vidioc_dqbuf(struct file *file, void *priv, | ||
958 | struct v4l2_buffer *p) | ||
959 | { | ||
960 | return videobuf_dqbuf(get_queue(file), p, | ||
961 | file->f_flags & O_NONBLOCK); | ||
962 | } | ||
963 | |||
964 | static int vidioc_streamon(struct file *file, void *priv, | ||
965 | enum v4l2_buf_type i) | ||
966 | { | ||
967 | struct cx23885_dev *dev = video_drvdata(file); | ||
968 | struct video_device *vdev = video_devdata(file); | ||
969 | struct cx23885_fh *fh = priv; | ||
970 | dprintk(1, "%s()\n", __func__); | ||
971 | |||
972 | if (vdev->vfl_type == VFL_TYPE_VBI && | ||
973 | i != V4L2_BUF_TYPE_VBI_CAPTURE) | ||
974 | return -EINVAL; | ||
975 | if (vdev->vfl_type == VFL_TYPE_GRABBER && | ||
976 | i != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
977 | return -EINVAL; | ||
978 | |||
979 | if (unlikely(!res_get(dev, fh, get_resource(i)))) | ||
980 | return -EBUSY; | ||
981 | |||
982 | /* Don't start VBI streaming unless vida streaming | ||
983 | * has already started. | ||
984 | */ | ||
985 | if ((i == V4L2_BUF_TYPE_VBI_CAPTURE) && | ||
986 | ((cx_read(VID_A_DMA_CTL) & 0x11) == 0)) | ||
987 | return -EINVAL; | ||
988 | |||
989 | return videobuf_streamon(get_queue(file)); | ||
990 | } | ||
991 | |||
992 | static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | ||
993 | { | ||
994 | struct cx23885_dev *dev = video_drvdata(file); | ||
995 | struct video_device *vdev = video_devdata(file); | ||
996 | struct cx23885_fh *fh = priv; | ||
997 | int err, res; | ||
998 | dprintk(1, "%s()\n", __func__); | ||
999 | |||
1000 | if (vdev->vfl_type == VFL_TYPE_VBI && | ||
1001 | i != V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1002 | return -EINVAL; | ||
1003 | if (vdev->vfl_type == VFL_TYPE_GRABBER && | ||
1004 | i != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1005 | return -EINVAL; | ||
1006 | |||
1007 | res = get_resource(i); | ||
1008 | err = videobuf_streamoff(get_queue(file)); | ||
1009 | if (err < 0) | ||
1010 | return err; | ||
1011 | res_free(dev, fh, res); | ||
1012 | return 0; | ||
1013 | } | ||
1014 | |||
1015 | static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) | 639 | static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) |
1016 | { | 640 | { |
1017 | struct cx23885_dev *dev = video_drvdata(file); | 641 | struct cx23885_dev *dev = video_drvdata(file); |
@@ -1288,7 +912,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, | |||
1288 | { | 912 | { |
1289 | struct v4l2_ctrl *mute; | 913 | struct v4l2_ctrl *mute; |
1290 | int old_mute_val = 1; | 914 | int old_mute_val = 1; |
1291 | struct videobuf_dvb_frontend *vfe; | 915 | struct vb2_dvb_frontend *vfe; |
1292 | struct dvb_frontend *fe; | 916 | struct dvb_frontend *fe; |
1293 | 917 | ||
1294 | struct analog_parameters params = { | 918 | struct analog_parameters params = { |
@@ -1312,7 +936,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, | |||
1312 | dprintk(1, "%s() frequency=%d tuner=%d std=0x%llx\n", __func__, | 936 | dprintk(1, "%s() frequency=%d tuner=%d std=0x%llx\n", __func__, |
1313 | params.frequency, f->tuner, params.std); | 937 | params.frequency, f->tuner, params.std); |
1314 | 938 | ||
1315 | vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1); | 939 | vfe = vb2_dvb_get_frontend(&dev->ts2.frontends, 1); |
1316 | if (!vfe) { | 940 | if (!vfe) { |
1317 | return -EINVAL; | 941 | return -EINVAL; |
1318 | } | 942 | } |
@@ -1368,28 +992,6 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
1368 | 992 | ||
1369 | /* ----------------------------------------------------------- */ | 993 | /* ----------------------------------------------------------- */ |
1370 | 994 | ||
1371 | static void cx23885_vid_timeout(unsigned long data) | ||
1372 | { | ||
1373 | struct cx23885_dev *dev = (struct cx23885_dev *)data; | ||
1374 | struct cx23885_dmaqueue *q = &dev->vidq; | ||
1375 | struct cx23885_buffer *buf; | ||
1376 | unsigned long flags; | ||
1377 | |||
1378 | spin_lock_irqsave(&dev->slock, flags); | ||
1379 | while (!list_empty(&q->active)) { | ||
1380 | buf = list_entry(q->active.next, | ||
1381 | struct cx23885_buffer, vb.queue); | ||
1382 | list_del(&buf->vb.queue); | ||
1383 | buf->vb.state = VIDEOBUF_ERROR; | ||
1384 | wake_up(&buf->vb.done); | ||
1385 | printk(KERN_ERR "%s: [%p/%d] timeout - dma=0x%08lx\n", | ||
1386 | dev->name, buf, buf->vb.i, | ||
1387 | (unsigned long)buf->risc.dma); | ||
1388 | } | ||
1389 | cx23885_restart_video_queue(dev, q); | ||
1390 | spin_unlock_irqrestore(&dev->slock, flags); | ||
1391 | } | ||
1392 | |||
1393 | int cx23885_video_irq(struct cx23885_dev *dev, u32 status) | 995 | int cx23885_video_irq(struct cx23885_dev *dev, u32 status) |
1394 | { | 996 | { |
1395 | u32 mask, count; | 997 | u32 mask, count; |
@@ -1434,13 +1036,6 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status) | |||
1434 | spin_unlock(&dev->slock); | 1036 | spin_unlock(&dev->slock); |
1435 | handled++; | 1037 | handled++; |
1436 | } | 1038 | } |
1437 | if (status & VID_BC_MSK_RISCI2) { | ||
1438 | dprintk(2, "stopper video\n"); | ||
1439 | spin_lock(&dev->slock); | ||
1440 | cx23885_restart_video_queue(dev, &dev->vidq); | ||
1441 | spin_unlock(&dev->slock); | ||
1442 | handled++; | ||
1443 | } | ||
1444 | 1039 | ||
1445 | /* Allow the VBI framework to process it's payload */ | 1040 | /* Allow the VBI framework to process it's payload */ |
1446 | handled += cx23885_vbi_irq(dev, status); | 1041 | handled += cx23885_vbi_irq(dev, status); |
@@ -1453,12 +1048,12 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status) | |||
1453 | 1048 | ||
1454 | static const struct v4l2_file_operations video_fops = { | 1049 | static const struct v4l2_file_operations video_fops = { |
1455 | .owner = THIS_MODULE, | 1050 | .owner = THIS_MODULE, |
1456 | .open = video_open, | 1051 | .open = v4l2_fh_open, |
1457 | .release = video_release, | 1052 | .release = vb2_fop_release, |
1458 | .read = video_read, | 1053 | .read = vb2_fop_read, |
1459 | .poll = video_poll, | 1054 | .poll = vb2_fop_poll, |
1460 | .mmap = video_mmap, | ||
1461 | .unlocked_ioctl = video_ioctl2, | 1055 | .unlocked_ioctl = video_ioctl2, |
1056 | .mmap = vb2_fop_mmap, | ||
1462 | }; | 1057 | }; |
1463 | 1058 | ||
1464 | static const struct v4l2_ioctl_ops video_ioctl_ops = { | 1059 | static const struct v4l2_ioctl_ops video_ioctl_ops = { |
@@ -1470,18 +1065,19 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1470 | .vidioc_g_fmt_vbi_cap = cx23885_vbi_fmt, | 1065 | .vidioc_g_fmt_vbi_cap = cx23885_vbi_fmt, |
1471 | .vidioc_try_fmt_vbi_cap = cx23885_vbi_fmt, | 1066 | .vidioc_try_fmt_vbi_cap = cx23885_vbi_fmt, |
1472 | .vidioc_s_fmt_vbi_cap = cx23885_vbi_fmt, | 1067 | .vidioc_s_fmt_vbi_cap = cx23885_vbi_fmt, |
1473 | .vidioc_reqbufs = vidioc_reqbufs, | 1068 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
1474 | .vidioc_querybuf = vidioc_querybuf, | 1069 | .vidioc_prepare_buf = vb2_ioctl_prepare_buf, |
1475 | .vidioc_qbuf = vidioc_qbuf, | 1070 | .vidioc_querybuf = vb2_ioctl_querybuf, |
1476 | .vidioc_dqbuf = vidioc_dqbuf, | 1071 | .vidioc_qbuf = vb2_ioctl_qbuf, |
1072 | .vidioc_dqbuf = vb2_ioctl_dqbuf, | ||
1073 | .vidioc_streamon = vb2_ioctl_streamon, | ||
1074 | .vidioc_streamoff = vb2_ioctl_streamoff, | ||
1477 | .vidioc_s_std = vidioc_s_std, | 1075 | .vidioc_s_std = vidioc_s_std, |
1478 | .vidioc_g_std = vidioc_g_std, | 1076 | .vidioc_g_std = vidioc_g_std, |
1479 | .vidioc_enum_input = vidioc_enum_input, | 1077 | .vidioc_enum_input = vidioc_enum_input, |
1480 | .vidioc_g_input = vidioc_g_input, | 1078 | .vidioc_g_input = vidioc_g_input, |
1481 | .vidioc_s_input = vidioc_s_input, | 1079 | .vidioc_s_input = vidioc_s_input, |
1482 | .vidioc_log_status = vidioc_log_status, | 1080 | .vidioc_log_status = vidioc_log_status, |
1483 | .vidioc_streamon = vidioc_streamon, | ||
1484 | .vidioc_streamoff = vidioc_streamoff, | ||
1485 | .vidioc_g_tuner = vidioc_g_tuner, | 1081 | .vidioc_g_tuner = vidioc_g_tuner, |
1486 | .vidioc_s_tuner = vidioc_s_tuner, | 1082 | .vidioc_s_tuner = vidioc_s_tuner, |
1487 | .vidioc_g_frequency = vidioc_g_frequency, | 1083 | .vidioc_g_frequency = vidioc_g_frequency, |
@@ -1517,7 +1113,6 @@ void cx23885_video_unregister(struct cx23885_dev *dev) | |||
1517 | else | 1113 | else |
1518 | video_device_release(dev->vbi_dev); | 1114 | video_device_release(dev->vbi_dev); |
1519 | dev->vbi_dev = NULL; | 1115 | dev->vbi_dev = NULL; |
1520 | btcx_riscmem_free(dev->pci, &dev->vbiq.stopper); | ||
1521 | } | 1116 | } |
1522 | if (dev->video_dev) { | 1117 | if (dev->video_dev) { |
1523 | if (video_is_registered(dev->video_dev)) | 1118 | if (video_is_registered(dev->video_dev)) |
@@ -1525,8 +1120,6 @@ void cx23885_video_unregister(struct cx23885_dev *dev) | |||
1525 | else | 1120 | else |
1526 | video_device_release(dev->video_dev); | 1121 | video_device_release(dev->video_dev); |
1527 | dev->video_dev = NULL; | 1122 | dev->video_dev = NULL; |
1528 | |||
1529 | btcx_riscmem_free(dev->pci, &dev->vidq.stopper); | ||
1530 | } | 1123 | } |
1531 | 1124 | ||
1532 | if (dev->audio_dev) | 1125 | if (dev->audio_dev) |
@@ -1535,6 +1128,7 @@ void cx23885_video_unregister(struct cx23885_dev *dev) | |||
1535 | 1128 | ||
1536 | int cx23885_video_register(struct cx23885_dev *dev) | 1129 | int cx23885_video_register(struct cx23885_dev *dev) |
1537 | { | 1130 | { |
1131 | struct vb2_queue *q; | ||
1538 | int err; | 1132 | int err; |
1539 | 1133 | ||
1540 | dprintk(1, "%s()\n", __func__); | 1134 | dprintk(1, "%s()\n", __func__); |
@@ -1551,21 +1145,9 @@ int cx23885_video_register(struct cx23885_dev *dev) | |||
1551 | 1145 | ||
1552 | /* init video dma queues */ | 1146 | /* init video dma queues */ |
1553 | INIT_LIST_HEAD(&dev->vidq.active); | 1147 | INIT_LIST_HEAD(&dev->vidq.active); |
1554 | INIT_LIST_HEAD(&dev->vidq.queued); | ||
1555 | dev->vidq.timeout.function = cx23885_vid_timeout; | ||
1556 | dev->vidq.timeout.data = (unsigned long)dev; | ||
1557 | init_timer(&dev->vidq.timeout); | ||
1558 | cx23885_risc_stopper(dev->pci, &dev->vidq.stopper, | ||
1559 | VID_A_DMA_CTL, 0x11, 0x00); | ||
1560 | 1148 | ||
1561 | /* init vbi dma queues */ | 1149 | /* init vbi dma queues */ |
1562 | INIT_LIST_HEAD(&dev->vbiq.active); | 1150 | INIT_LIST_HEAD(&dev->vbiq.active); |
1563 | INIT_LIST_HEAD(&dev->vbiq.queued); | ||
1564 | dev->vbiq.timeout.function = cx23885_vbi_timeout; | ||
1565 | dev->vbiq.timeout.data = (unsigned long)dev; | ||
1566 | init_timer(&dev->vbiq.timeout); | ||
1567 | cx23885_risc_stopper(dev->pci, &dev->vbiq.stopper, | ||
1568 | VID_A_DMA_CTL, 0x22, 0x00); | ||
1569 | 1151 | ||
1570 | cx23885_irq_add_enable(dev, 0x01); | 1152 | cx23885_irq_add_enable(dev, 0x01); |
1571 | 1153 | ||
@@ -1626,9 +1208,42 @@ int cx23885_video_register(struct cx23885_dev *dev) | |||
1626 | cx23885_audio_mux(dev, 0); | 1208 | cx23885_audio_mux(dev, 0); |
1627 | mutex_unlock(&dev->lock); | 1209 | mutex_unlock(&dev->lock); |
1628 | 1210 | ||
1211 | q = &dev->vb2_vidq; | ||
1212 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1213 | q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; | ||
1214 | q->gfp_flags = GFP_DMA32; | ||
1215 | q->min_buffers_needed = 2; | ||
1216 | q->drv_priv = dev; | ||
1217 | q->buf_struct_size = sizeof(struct cx23885_buffer); | ||
1218 | q->ops = &cx23885_video_qops; | ||
1219 | q->mem_ops = &vb2_dma_sg_memops; | ||
1220 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
1221 | q->lock = &dev->lock; | ||
1222 | |||
1223 | err = vb2_queue_init(q); | ||
1224 | if (err < 0) | ||
1225 | goto fail_unreg; | ||
1226 | |||
1227 | q = &dev->vb2_vbiq; | ||
1228 | q->type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
1229 | q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; | ||
1230 | q->gfp_flags = GFP_DMA32; | ||
1231 | q->min_buffers_needed = 2; | ||
1232 | q->drv_priv = dev; | ||
1233 | q->buf_struct_size = sizeof(struct cx23885_buffer); | ||
1234 | q->ops = &cx23885_vbi_qops; | ||
1235 | q->mem_ops = &vb2_dma_sg_memops; | ||
1236 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
1237 | q->lock = &dev->lock; | ||
1238 | |||
1239 | err = vb2_queue_init(q); | ||
1240 | if (err < 0) | ||
1241 | goto fail_unreg; | ||
1242 | |||
1629 | /* register Video device */ | 1243 | /* register Video device */ |
1630 | dev->video_dev = cx23885_vdev_init(dev, dev->pci, | 1244 | dev->video_dev = cx23885_vdev_init(dev, dev->pci, |
1631 | &cx23885_video_template, "video"); | 1245 | &cx23885_video_template, "video"); |
1246 | dev->video_dev->queue = &dev->vb2_vidq; | ||
1632 | err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, | 1247 | err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, |
1633 | video_nr[dev->nr]); | 1248 | video_nr[dev->nr]); |
1634 | if (err < 0) { | 1249 | if (err < 0) { |
@@ -1642,6 +1257,7 @@ int cx23885_video_register(struct cx23885_dev *dev) | |||
1642 | /* register VBI device */ | 1257 | /* register VBI device */ |
1643 | dev->vbi_dev = cx23885_vdev_init(dev, dev->pci, | 1258 | dev->vbi_dev = cx23885_vdev_init(dev, dev->pci, |
1644 | &cx23885_vbi_template, "vbi"); | 1259 | &cx23885_vbi_template, "vbi"); |
1260 | dev->vbi_dev->queue = &dev->vb2_vbiq; | ||
1645 | err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, | 1261 | err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, |
1646 | vbi_nr[dev->nr]); | 1262 | vbi_nr[dev->nr]); |
1647 | if (err < 0) { | 1263 | if (err < 0) { |
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 5f5d8e8aa472..388e420d88e9 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h | |||
@@ -25,8 +25,8 @@ | |||
25 | #include <media/v4l2-ctrls.h> | 25 | #include <media/v4l2-ctrls.h> |
26 | #include <media/tuner.h> | 26 | #include <media/tuner.h> |
27 | #include <media/tveeprom.h> | 27 | #include <media/tveeprom.h> |
28 | #include <media/videobuf-dma-sg.h> | 28 | #include <media/videobuf2-dma-sg.h> |
29 | #include <media/videobuf-dvb.h> | 29 | #include <media/videobuf2-dvb.h> |
30 | #include <media/rc-core.h> | 30 | #include <media/rc-core.h> |
31 | 31 | ||
32 | #include "btcx-risc.h" | 32 | #include "btcx-risc.h" |
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | 37 | ||
38 | #define CX23885_VERSION "0.0.3" | 38 | #define CX23885_VERSION "0.0.4" |
39 | 39 | ||
40 | #define UNSET (-1U) | 40 | #define UNSET (-1U) |
41 | 41 | ||
@@ -44,9 +44,6 @@ | |||
44 | /* Max number of inputs by card */ | 44 | /* Max number of inputs by card */ |
45 | #define MAX_CX23885_INPUT 8 | 45 | #define MAX_CX23885_INPUT 8 |
46 | #define INPUT(nr) (&cx23885_boards[dev->board].input[nr]) | 46 | #define INPUT(nr) (&cx23885_boards[dev->board].input[nr]) |
47 | #define RESOURCE_OVERLAY 1 | ||
48 | #define RESOURCE_VIDEO 2 | ||
49 | #define RESOURCE_VBI 4 | ||
50 | 47 | ||
51 | #define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */ | 48 | #define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */ |
52 | 49 | ||
@@ -136,20 +133,6 @@ struct cx23885_tvnorm { | |||
136 | u32 cxoformat; | 133 | u32 cxoformat; |
137 | }; | 134 | }; |
138 | 135 | ||
139 | struct cx23885_fh { | ||
140 | struct v4l2_fh fh; | ||
141 | u32 resources; | ||
142 | struct cx23885_dev *q_dev; | ||
143 | |||
144 | /* vbi capture */ | ||
145 | struct videobuf_queue vidq; | ||
146 | struct videobuf_queue vbiq; | ||
147 | |||
148 | /* MPEG Encoder specifics ONLY */ | ||
149 | struct videobuf_queue mpegq; | ||
150 | atomic_t v4l_reading; | ||
151 | }; | ||
152 | |||
153 | enum cx23885_itype { | 136 | enum cx23885_itype { |
154 | CX23885_VMUX_COMPOSITE1 = 1, | 137 | CX23885_VMUX_COMPOSITE1 = 1, |
155 | CX23885_VMUX_COMPOSITE2, | 138 | CX23885_VMUX_COMPOSITE2, |
@@ -172,7 +155,8 @@ enum cx23885_src_sel_type { | |||
172 | /* buffer for one video frame */ | 155 | /* buffer for one video frame */ |
173 | struct cx23885_buffer { | 156 | struct cx23885_buffer { |
174 | /* common v4l buffer stuff -- must be first */ | 157 | /* common v4l buffer stuff -- must be first */ |
175 | struct videobuf_buffer vb; | 158 | struct vb2_buffer vb; |
159 | struct list_head queue; | ||
176 | 160 | ||
177 | /* cx23885 specific */ | 161 | /* cx23885 specific */ |
178 | unsigned int bpl; | 162 | unsigned int bpl; |
@@ -248,9 +232,6 @@ struct cx23885_i2c { | |||
248 | 232 | ||
249 | struct cx23885_dmaqueue { | 233 | struct cx23885_dmaqueue { |
250 | struct list_head active; | 234 | struct list_head active; |
251 | struct list_head queued; | ||
252 | struct timer_list timeout; | ||
253 | struct btcx_riscmem stopper; | ||
254 | u32 count; | 235 | u32 count; |
255 | }; | 236 | }; |
256 | 237 | ||
@@ -260,7 +241,7 @@ struct cx23885_tsport { | |||
260 | int nr; | 241 | int nr; |
261 | int sram_chno; | 242 | int sram_chno; |
262 | 243 | ||
263 | struct videobuf_dvb_frontends frontends; | 244 | struct vb2_dvb_frontends frontends; |
264 | 245 | ||
265 | /* dma queues */ | 246 | /* dma queues */ |
266 | struct cx23885_dmaqueue mpegq; | 247 | struct cx23885_dmaqueue mpegq; |
@@ -389,7 +370,6 @@ struct cx23885_dev { | |||
389 | } bridge; | 370 | } bridge; |
390 | 371 | ||
391 | /* Analog video */ | 372 | /* Analog video */ |
392 | u32 resources; | ||
393 | unsigned int input; | 373 | unsigned int input; |
394 | unsigned int audinput; /* Selectable audio input */ | 374 | unsigned int audinput; /* Selectable audio input */ |
395 | u32 tvaudio; | 375 | u32 tvaudio; |
@@ -420,16 +400,20 @@ struct cx23885_dev { | |||
420 | /* video capture */ | 400 | /* video capture */ |
421 | struct cx23885_fmt *fmt; | 401 | struct cx23885_fmt *fmt; |
422 | unsigned int width, height; | 402 | unsigned int width, height; |
403 | unsigned field; | ||
423 | 404 | ||
424 | struct cx23885_dmaqueue vidq; | 405 | struct cx23885_dmaqueue vidq; |
406 | struct vb2_queue vb2_vidq; | ||
425 | struct cx23885_dmaqueue vbiq; | 407 | struct cx23885_dmaqueue vbiq; |
408 | struct vb2_queue vb2_vbiq; | ||
409 | |||
426 | spinlock_t slock; | 410 | spinlock_t slock; |
427 | 411 | ||
428 | /* MPEG Encoder ONLY settings */ | 412 | /* MPEG Encoder ONLY settings */ |
429 | u32 cx23417_mailbox; | 413 | u32 cx23417_mailbox; |
430 | struct cx2341x_handler cxhdl; | 414 | struct cx2341x_handler cxhdl; |
431 | struct video_device *v4l_device; | 415 | struct video_device *v4l_device; |
432 | atomic_t v4l_reader_count; | 416 | struct vb2_queue vb2_mpegq; |
433 | struct cx23885_tvnorm encodernorm; | 417 | struct cx23885_tvnorm encodernorm; |
434 | 418 | ||
435 | /* Analog raw audio */ | 419 | /* Analog raw audio */ |
@@ -505,9 +489,6 @@ extern int cx23885_sram_channel_setup(struct cx23885_dev *dev, | |||
505 | extern void cx23885_sram_channel_dump(struct cx23885_dev *dev, | 489 | extern void cx23885_sram_channel_dump(struct cx23885_dev *dev, |
506 | struct sram_channel *ch); | 490 | struct sram_channel *ch); |
507 | 491 | ||
508 | extern int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | ||
509 | u32 reg, u32 mask, u32 value); | ||
510 | |||
511 | extern int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, | 492 | extern int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, |
512 | struct scatterlist *sglist, | 493 | struct scatterlist *sglist, |
513 | unsigned int top_offset, unsigned int bottom_offset, | 494 | unsigned int top_offset, unsigned int bottom_offset, |
@@ -518,13 +499,11 @@ extern int cx23885_risc_vbibuffer(struct pci_dev *pci, | |||
518 | unsigned int top_offset, unsigned int bottom_offset, | 499 | unsigned int top_offset, unsigned int bottom_offset, |
519 | unsigned int bpl, unsigned int padding, unsigned int lines); | 500 | unsigned int bpl, unsigned int padding, unsigned int lines); |
520 | 501 | ||
502 | int cx23885_start_dma(struct cx23885_tsport *port, | ||
503 | struct cx23885_dmaqueue *q, | ||
504 | struct cx23885_buffer *buf); | ||
521 | void cx23885_cancel_buffers(struct cx23885_tsport *port); | 505 | void cx23885_cancel_buffers(struct cx23885_tsport *port); |
522 | 506 | ||
523 | extern int cx23885_restart_queue(struct cx23885_tsport *port, | ||
524 | struct cx23885_dmaqueue *q); | ||
525 | |||
526 | extern void cx23885_wakeup(struct cx23885_tsport *port, | ||
527 | struct cx23885_dmaqueue *q, u32 count); | ||
528 | 507 | ||
529 | extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask); | 508 | extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask); |
530 | extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask); | 509 | extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask); |
@@ -558,13 +537,11 @@ extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev); | |||
558 | extern int cx23885_dvb_register(struct cx23885_tsport *port); | 537 | extern int cx23885_dvb_register(struct cx23885_tsport *port); |
559 | extern int cx23885_dvb_unregister(struct cx23885_tsport *port); | 538 | extern int cx23885_dvb_unregister(struct cx23885_tsport *port); |
560 | 539 | ||
561 | extern int cx23885_buf_prepare(struct videobuf_queue *q, | 540 | extern int cx23885_buf_prepare(struct cx23885_buffer *buf, |
562 | struct cx23885_tsport *port, | 541 | struct cx23885_tsport *port); |
563 | struct cx23885_buffer *buf, | ||
564 | enum v4l2_field field); | ||
565 | extern void cx23885_buf_queue(struct cx23885_tsport *port, | 542 | extern void cx23885_buf_queue(struct cx23885_tsport *port, |
566 | struct cx23885_buffer *buf); | 543 | struct cx23885_buffer *buf); |
567 | extern void cx23885_free_buffer(struct videobuf_queue *q, | 544 | extern void cx23885_free_buffer(struct cx23885_dev *dev, |
568 | struct cx23885_buffer *buf); | 545 | struct cx23885_buffer *buf); |
569 | 546 | ||
570 | /* ----------------------------------------------------------- */ | 547 | /* ----------------------------------------------------------- */ |
@@ -586,9 +563,7 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm); | |||
586 | extern int cx23885_vbi_fmt(struct file *file, void *priv, | 563 | extern int cx23885_vbi_fmt(struct file *file, void *priv, |
587 | struct v4l2_format *f); | 564 | struct v4l2_format *f); |
588 | extern void cx23885_vbi_timeout(unsigned long data); | 565 | extern void cx23885_vbi_timeout(unsigned long data); |
589 | extern struct videobuf_queue_ops cx23885_vbi_qops; | 566 | extern struct vb2_ops cx23885_vbi_qops; |
590 | extern int cx23885_restart_vbi_queue(struct cx23885_dev *dev, | ||
591 | struct cx23885_dmaqueue *q); | ||
592 | extern int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status); | 567 | extern int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status); |
593 | 568 | ||
594 | /* cx23885-i2c.c */ | 569 | /* cx23885-i2c.c */ |