summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/cx18/cx18-driver.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2008-12-14 01:11:29 -0200
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-14 01:11:29 -0200
commita8b91214d1d10d63bca3f2f9f8d4670f46a0b782 (patch)
treea66ea5b43a176a253b5722c3fb1c6e9b23e5fb5d /linux/drivers/media/video/cx18/cx18-driver.c
parent97b478e31ccddc358a73628542bb2d32983abeac (diff)
parent61a2de789c256e6a8c6c184ed07b18f06b19e1dd (diff)
downloadmediapointer-dvb-s2-a8b91214d1d10d63bca3f2f9f8d4670f46a0b782.tar.gz
mediapointer-dvb-s2-a8b91214d1d10d63bca3f2f9f8d4670f46a0b782.tar.bz2
merge: http://linuxtv.org/hg/~awalls/v4l-dvb
From: Mauro Carvalho Chehab <mchehab@redhat.com> Priority: normal Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'linux/drivers/media/video/cx18/cx18-driver.c')
-rw-r--r--linux/drivers/media/video/cx18/cx18-driver.c205
1 files changed, 183 insertions, 22 deletions
diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c
index 57fcce84b..cea4735b6 100644
--- a/linux/drivers/media/video/cx18/cx18-driver.c
+++ b/linux/drivers/media/video/cx18/cx18-driver.c
@@ -83,12 +83,28 @@ static char secam[] = "--";
static char ntsc[] = "-";
/* Buffers */
-static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS;
static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS;
+static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS;
+static int enc_idx_buffers = CX18_DEFAULT_ENC_IDX_BUFFERS;
static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS;
static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS;
static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
+static int enc_ts_bufsize = CX18_DEFAULT_ENC_TS_BUFSIZE;
+static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE;
+static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE;
+static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE;
+/* VBI bufsize based on standards supported by card tuner for now */
+static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE;
+
+static int enc_ts_bufs = -1;
+static int enc_mpg_bufs = -1;
+static int enc_idx_bufs = -1;
+static int enc_yuv_bufs = -1;
+static int enc_vbi_bufs = -1;
+static int enc_pcm_bufs = -1;
+
+
static int cx18_pci_latency = 1;
static int mmio_ndelay;
@@ -108,12 +124,27 @@ module_param(retry_mmio, int, 0644);
module_param(cx18_pci_latency, int, 0644);
module_param(cx18_first_minor, int, 0644);
-module_param(enc_mpg_buffers, int, 0644);
module_param(enc_ts_buffers, int, 0644);
+module_param(enc_mpg_buffers, int, 0644);
+module_param(enc_idx_buffers, int, 0644);
module_param(enc_yuv_buffers, int, 0644);
module_param(enc_vbi_buffers, int, 0644);
module_param(enc_pcm_buffers, int, 0644);
+module_param(enc_ts_bufsize, int, 0644);
+module_param(enc_mpg_bufsize, int, 0644);
+module_param(enc_idx_bufsize, int, 0644);
+module_param(enc_yuv_bufsize, int, 0644);
+/* VBI bufsize based on standards supported by card tuner for now */
+module_param(enc_pcm_bufsize, int, 0644);
+
+module_param(enc_ts_bufs, int, 0644);
+module_param(enc_mpg_bufs, int, 0644);
+module_param(enc_idx_bufs, int, 0644);
+module_param(enc_yuv_bufs, int, 0644);
+module_param(enc_vbi_bufs, int, 0644);
+module_param(enc_pcm_bufs, int, 0644);
+
MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
"\t\t\tsee tuner.h for values");
MODULE_PARM_DESC(radio,
@@ -154,21 +185,57 @@ MODULE_PARM_DESC(retry_mmio,
MODULE_PARM_DESC(mmio_ndelay,
"(Deprecated) MMIO accesses are now never purposely delayed\n"
"\t\t\tEffectively: 0 ns");
-MODULE_PARM_DESC(enc_mpg_buffers,
- "Encoder MPG Buffers (in MB)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
MODULE_PARM_DESC(enc_ts_buffers,
- "Encoder TS Buffers (in MB)\n"
+ "Encoder TS buffer memory (MB). (enc_ts_bufs can override)\n"
"\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS));
+MODULE_PARM_DESC(enc_ts_bufsize,
+ "Size of an encoder TS buffer (kB)\n"
+ "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFSIZE));
+MODULE_PARM_DESC(enc_ts_bufs,
+ "Number of encoder TS buffers\n"
+ "\t\t\tDefault is computed from other enc_ts_* parameters");
+MODULE_PARM_DESC(enc_mpg_buffers,
+ "Encoder MPG buffer memory (MB). (enc_mpg_bufs can override)\n"
+ "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
+MODULE_PARM_DESC(enc_mpg_bufsize,
+ "Size of an encoder MPG buffer (kB)\n"
+ "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFSIZE));
+MODULE_PARM_DESC(enc_mpg_bufs,
+ "Number of encoder MPG buffers\n"
+ "\t\t\tDefault is computed from other enc_mpg_* parameters");
+MODULE_PARM_DESC(enc_idx_buffers,
+ "Encoder IDX buffer memory (MB). (enc_idx_bufs can override)\n"
+ "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFFERS));
+MODULE_PARM_DESC(enc_idx_bufsize,
+ "Size of an encoder IDX buffer (kB)\n"
+ "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFSIZE));
+MODULE_PARM_DESC(enc_idx_bufs,
+ "Number of encoder IDX buffers\n"
+ "\t\t\tDefault is computed from other enc_idx_* parameters");
MODULE_PARM_DESC(enc_yuv_buffers,
- "Encoder YUV Buffers (in MB)\n"
+ "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n"
"\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
+MODULE_PARM_DESC(enc_yuv_bufsize,
+ "Size of an encoder YUV buffer (kB)\n"
+ "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFSIZE));
+MODULE_PARM_DESC(enc_yuv_bufs,
+ "Number of encoder YUV buffers\n"
+ "\t\t\tDefault is computed from other enc_yuv_* parameters");
MODULE_PARM_DESC(enc_vbi_buffers,
- "Encoder VBI Buffers (in MB)\n"
+ "Encoder VBI buffer memory (MB). (enc_vbi_bufs can override)\n"
"\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
+MODULE_PARM_DESC(enc_vbi_bufs,
+ "Number of encoder VBI buffers\n"
+ "\t\t\tDefault is computed from enc_vbi_buffers & tuner std");
MODULE_PARM_DESC(enc_pcm_buffers,
- "Encoder PCM buffers (in MB)\n"
+ "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n"
"\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
+MODULE_PARM_DESC(enc_pcm_bufsize,
+ "Size of an encoder PCM buffer (kB)\n"
+ "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFSIZE));
+MODULE_PARM_DESC(enc_pcm_bufs,
+ "Number of encoder PCM buffers\n"
+ "\t\t\tDefault is computed from other enc_pcm_* parameters");
MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card");
@@ -361,11 +428,65 @@ static void cx18_process_options(struct cx18 *cx)
{
int i, j;
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers;
+ cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
+ cx->options.megabytes[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_buffers;
cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
+ cx->options.megabytes[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control only */
+
+ cx->stream_buffers[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufs;
+ cx->stream_buffers[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufs;
+ cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufs;
+ cx->stream_buffers[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufs;
+ cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_bufs;
+ cx->stream_buffers[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufs;
+ cx->stream_buffers[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control, no data */
+
+ cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufsize;
+ cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
+ cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
+ cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
+ cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */
+ cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
+ cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */
+
+ /* Except for VBI ensure stream_buffers & stream_buf_size are valid */
+ for (i = 0; i < CX18_MAX_STREAMS; i++) {
+ /* User said to use 0 buffers */
+ if (cx->stream_buffers[i] == 0) {
+ cx->options.megabytes[i] = 0;
+ cx->stream_buf_size[i] = 0;
+ continue;
+ }
+ /* User said to use 0 MB total */
+ if (cx->options.megabytes[i] <= 0) {
+ cx->options.megabytes[i] = 0;
+ cx->stream_buffers[i] = 0;
+ cx->stream_buf_size[i] = 0;
+ continue;
+ }
+ /* VBI is computed later or user said buffer has size 0 */
+ if (cx->stream_buf_size[i] <= 0) {
+ if (i != CX18_ENC_STREAM_TYPE_VBI) {
+ cx->options.megabytes[i] = 0;
+ cx->stream_buffers[i] = 0;
+ cx->stream_buf_size[i] = 0;
+ }
+ continue;
+ }
+ if (cx->stream_buffers[i] < 0) {
+ cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
+ / cx->stream_buf_size[i];
+ } else {
+ /* N.B. This might round down to 0 */
+ cx->options.megabytes[i] =
+ cx->stream_buffers[i] * cx->stream_buf_size[i] / 1024;
+ }
+ cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */
+ }
+
cx->options.cardtype = cardtype[cx->num];
cx->options.tuner = tuner[cx->num];
cx->options.radio = radio[cx->num];
@@ -478,15 +599,49 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
init_waitqueue_head(&cx->dma_waitq);
/* VBI */
- cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+ cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
- cx->vbi.raw_size = 1456;
- cx->vbi.raw_decoder_line_size = 1456;
- cx->vbi.raw_decoder_sav_odd_field = 0x20;
- cx->vbi.raw_decoder_sav_even_field = 0x60;
- cx->vbi.sliced_decoder_line_size = 272;
- cx->vbi.sliced_decoder_sav_odd_field = 0xB0;
- cx->vbi.sliced_decoder_sav_even_field = 0xF0;
+
+ /*
+ * The VBI line sizes depend on the pixel clock and the horiz rate
+ *
+ * (1/Fh)*(2*Fp) = Samples/line
+ * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
+ *
+ * Sliced VBI is sent as ancillary data during horizontal blanking
+ * Raw VBI is sent as active video samples during vertcal blanking
+ *
+ * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
+ * length of 720 pixels @ 4:2:2 sampling. Thus...
+ *
+ * For NTSC:
+ *
+ * (1/15,734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
+ * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
+ *
+ * For PAL:
+ *
+ * (1/15,625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
+ * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
+ *
+ */
+
+ /* CX18-AV-Core number of VBI samples output per horizontal line */
+ cx->vbi.raw_decoder_line_size = 1444; /* 4 byte SAV + 2 * 720 */
+ cx->vbi.sliced_decoder_line_size = 272; /* 60 Hz: 268+4, 50 Hz: 280+4 */
+
+ /* CX18-AV-Core VBI samples/line possibly rounded up */
+ cx->vbi.raw_size = 1444; /* Real max size is 1444 */
+ cx->vbi.sliced_size = 284; /* Real max size is 284 */
+
+ /*
+ * CX18-AV-Core SAV/EAV RP codes in VIP 1.x mode
+ * Task Field VerticalBlank HorizontalBlank 0 0 0 0
+ */
+ cx->vbi.raw_decoder_sav_odd_field = 0x20; /* V */
+ cx->vbi.raw_decoder_sav_even_field = 0x60; /* FV */
+ cx->vbi.sliced_decoder_sav_odd_field = 0xB0; /* T VH - actually EAV */
+ cx->vbi.sliced_decoder_sav_even_field = 0xF0; /* TFVH - actually EAV */
return 0;
}
@@ -519,6 +674,7 @@ static void __devinit cx18_init_struct2(struct cx18 *cx)
cx->av_state.aud_input = CX18_AV_AUDIO8;
cx->av_state.audclk_freq = 48000;
cx->av_state.audmode = V4L2_TUNER_MODE_LANG1;
+ /* FIXME - 8 is NTSC value, investigate */
cx->av_state.vbi_line_offset = 8;
}
@@ -773,13 +929,18 @@ static int __devinit cx18_probe(struct pci_dev *dev,
}
cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = 0x08000;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = 0x08000;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = 0x01200;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = 0x20000;
vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
+ if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0)
+ cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] =
+ cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024
+ / vbi_buf_size;
+ else
+ cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] =
+ cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size
+ / (1024 * 1024);
+
if (cx->options.radio > 0)
cx->v4l2_cap |= V4L2_CAP_RADIO;