summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/cx88/cx88-blackbird.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/cx88/cx88-blackbird.c')
-rw-r--r--linux/drivers/media/video/cx88/cx88-blackbird.c539
1 files changed, 317 insertions, 222 deletions
diff --git a/linux/drivers/media/video/cx88/cx88-blackbird.c b/linux/drivers/media/video/cx88/cx88-blackbird.c
index 5d1b83107..51f4b1e9a 100644
--- a/linux/drivers/media/video/cx88/cx88-blackbird.c
+++ b/linux/drivers/media/video/cx88/cx88-blackbird.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-blackbird.c,v 1.4 2004/08/23 10:38:54 kraxel Exp $
+ * $Id: cx88-blackbird.c,v 1.5 2004/08/25 14:47:53 kraxel Exp $
*
* Support for a cx23416 mpeg encoder via cx2388x host port.
* "blackbird" reference design.
@@ -34,9 +34,23 @@
#include "cx88.h"
MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards");
-MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
+MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
+MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");
+static unsigned int mpegbufs = 8;
+MODULE_PARM(mpegbufs,"i");
+MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32");
+
+static unsigned int debug = 0;
+MODULE_PARM(debug,"i");
+MODULE_PARM_DESC(debug,"enable debug messages [blackbird]");
+
+#define dprintk(level,fmt, arg...) if (debug >= level) \
+ printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg)
+
+static struct list_head cx8802_devlist;
+
/* ------------------------------------------------------------------ */
#define BLACKBIRD_FIRM_ENC_FILENAME "blackbird-fw-enc.bin"
@@ -222,364 +236,357 @@ static int register_read(struct cx88_core *core, u32 address, u32 *value)
/* ------------------------------------------------------------------ */
-#if 0
-
/* We don't need to call the API often, so using just one mailbox will probably suffice */
-int blackbird_cmd(struct cx8802_dev *dev, u32 command, u32 inputcnt, u32 outputcnt, ...)
+static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command,
+ u32 inputcnt, u32 outputcnt, ...)
{
va_list args;
va_start(args, outputcnt);
+ unsigned long timeout;
+ u32 value, flag, retval;
int i;
- u32 value;
- u32 flag;
dprintk(1,"%s: 0x%X\n", __FUNCTION__, command);
/* this may not be 100% safe if we can't read any memory location
without side effects */
- memory_read(dev, dev->mpegport_mailbox - 4, &value);
+ memory_read(dev->core, dev->mailbox - 4, &value);
if (value != 0x12345678) {
dprintk(0, "Firmware and/or mailbox pointer not initialized or corrupted\n");
return -1;
}
- memory_read(dev, dev->mpegport_mailbox, &flag);
+ memory_read(dev->core, dev->mailbox, &flag);
if (flag) {
dprintk(0, "ERROR: Mailbox appears to be in use (%x)\n", flag);
return -1;
}
flag |= 1; /* tell 'em we're working on it */
- memory_write(dev, dev->mpegport_mailbox, flag);
+ memory_write(dev->core, dev->mailbox, flag);
- memory_write(dev, dev->mpegport_mailbox + 1, command); /* command code */
- memory_write(dev, dev->mpegport_mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */
-
- /* write input values */
+ /* write command + args + fill remaining with zeros */
+ memory_write(dev->core, dev->mailbox + 1, command); /* command code */
+ memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */
for (i = 0; i < inputcnt ; i++) {
- u32 value = va_arg(args, int);
- memory_write(dev, dev->mpegport_mailbox + 4 + i, value);
+ value = va_arg(args, int);
+ memory_write(dev->core, dev->mailbox + 4 + i, value);
dprintk(1, "API Input %d = %d\n", i, value);
}
-
- /* fill with zeroes (ivtv does it, but is this necessary?) */
- for (; i < 16 ; i++) {
- u32 value = 0;
- memory_write(dev, dev->mpegport_mailbox + 4 + i, value);
- }
+ for (; i < 16 ; i++)
+ memory_write(dev->core, dev->mailbox + 4 + i, 0);
flag |= 3; /* tell 'em we're done writing */
- memory_write(dev, dev->mpegport_mailbox, flag);
+ memory_write(dev->core, dev->mailbox, flag);
/* wait for firmware to handle the API command */
- int timeoutcnt = 500; /* trial and error plus a margin (longest command I've seen is capture start) */
- do {
+ timeout = jiffies + msecs_to_jiffies(10);
+ for (;;) {
+ memory_read(dev->core, dev->mailbox, &flag);
+ if (0 == (flag & 4))
+ break;
+ if (time_after(jiffies,timeout)) {
+ dprintk(0, "ERROR: API Mailbox timeout\n");
+ return -1;
+ }
udelay(10);
- timeoutcnt--;
- memory_read(dev, dev->mpegport_mailbox, &flag);
- } while (timeoutcnt && ((flag & 4)==0));
-
- if (!timeoutcnt) {
- dprintk(0, "ERROR: API Mailbox timeout\n");
- flag = 0;
- memory_write(dev, dev->mpegport_mailbox, flag);
- return -1;
}
-
+
/* read output values */
for (i = 0; i < outputcnt ; i++) {
- u32 *value = va_arg(args, int *);
- memory_read(dev, dev->mpegport_mailbox + 4 + i, value);
- dprintk(1, "API Output %d = %d\n", i, *value);
+ int *vptr = va_arg(args, int *);
+ memory_read(dev->core, dev->mailbox + 4 + i, vptr);
+ dprintk(1, "API Output %d = %d\n", i, *vptr);
}
-
va_end(args);
- u32 retval;
- memory_read(dev, dev->mpegport_mailbox + 2, &retval);
- dprintk(1, "API result = %d (timeoutcnt=%d)\n",retval, timeoutcnt);
+ memory_read(dev->core, dev->mailbox + 2, &retval);
+ dprintk(1, "API result = %d\n",retval);
+
flag = 0;
- memory_write(dev, dev->mpegport_mailbox, flag);
+ memory_write(dev->core, dev->mailbox, flag);
return retval;
}
-int mpegport_find_mailbox(struct cx8800_dev *dev)
+static int blackbird_find_mailbox(struct cx8802_dev *dev)
{
u32 signature[4]={0x12345678, 0x34567812, 0x56781234, 0x78123456};
int signaturecnt=0;
+ u32 value;
int i;
- for (i = 0; (i < BLACKBIRD_FIRM_IMAGE_SIZE) && (signaturecnt < 4) ; i++)
- {
- u32 value;
- memory_read(dev, i, &value);
+
+ for (i = 0; i < BLACKBIRD_FIRM_IMAGE_SIZE; i++) {
+ memory_read(dev->core, i, &value);
if (value == signature[signaturecnt])
signaturecnt++;
else
signaturecnt = 0;
+ if (4 == signaturecnt) {
+ dprintk(1, "Mailbox signature found\n");
+ return i;
+ }
}
- if (signaturecnt == 4)
- {
- dprintk(1, "Mailbox signature found\n");
- return i;
- }
- else
- {
- dprintk(0, "Mailbox signature values not found!\n");
- return -1;
- }
+ dprintk(0, "Mailbox signature values not found!\n");
+ return -1;
}
-int mpegport_load_firmware(struct cx8800_dev *dev)
+static int blackbird_load_firmware(struct cx8802_dev *dev)
{
- dprintk(1,"Loading firmware\n");
+ static const unsigned char magic[8] = {
+ 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
+ };
+ const struct firmware *firmware;
int i, retval = 0;
u32 value = 0;
- const struct firmware *blackbird_firmware;
-
- retval = register_write(dev, IVTV_REG_VPU, 0xFFFFFFED);
- //retval = register_write(dev, IVTV_REG_VPU, 0xFFFFFFEF);
- retval |= register_write(dev, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
- retval |= register_write(dev, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640);
- retval |= register_write(dev, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
- udelay(500);
- retval |= register_write(dev, IVTV_REG_APU, 0);
-
- if (retval < 0) dprintk(0, "Error with register_write\n");
+ u32 checksum = 0;
+ u32 *dataptr;
- /* without this, the encoder chip is just a dead chip */
+ retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED);
+ retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
+ retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640);
+ retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
+ msleep(1);
+ retval |= register_write(dev->core, IVTV_REG_APU, 0);
- /* for this to work, 'apt-get install hotplug' and copy the firmware binary to /usr/lib/hotplug/firmware */
- retval = request_firmware(&blackbird_firmware, BLACKBIRD_FIRM_ENC_FILENAME, &dev->pci->dev);
+ if (retval < 0)
+ dprintk(0, "Error with register_write\n");
+ retval = request_firmware(&firmware, BLACKBIRD_FIRM_ENC_FILENAME,
+ &dev->pci->dev);
if (retval != 0) {
- dprintk(0, "ERROR: Hotplug firmware request failed! Fatal for mpegport support!\n");
- dprintk(0, "********** Perhaps hotplug utilities or the firmware file is not installed?\n");
- dprintk(0, "********** Or kernel hotplug support of Firmware loading support is not enabled?\n");
- dprintk(0, "********** - Kernel setup: Your kernel needs the following options:\n");
- dprintk(0, "********** 1) enable CONFIG_HOTPLUG from \"General Setup\"/\"Support for hot-pluggable devices\"\n");
- dprintk(0, "********** 2) enable CONFIG_FW_LOADER from \"Device Drivers\"/\"Generic Driver Options\"/\"Hotplug firmware loading support\"\n");
- dprintk(0, "********** - Hotplug support utilities:\n");
- dprintk(0, "********** 1) make sure sysfs is mounted on /sys\n");
- dprintk(0, "********** 2) copy the firmware binary to /usr/lib/hotplug/firmware/" BLACKBIRD_FIRM_ENC_FILENAME "\n");
- dprintk(0, "********** 3) Debian: 'apt-get install hotplug'\n");
- dprintk(0, "********** Others: Unknown (ask your vendor) or go here http://linux-hotplug.sourceforge.net/\n");
- dprintk(0, "********** You will also probably want to have a /etc/hotplug/firmware.agent\n");
+ dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n",
+ BLACKBIRD_FIRM_ENC_FILENAME);
+ dprintk(0, "Please fix your hotplug setup, the board will "
+ "not work without firmware loaded!\n");
return -1;
}
- if (blackbird_firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) {
- dprintk(0, "ERROR: Firmware is %d bytes long, which should be %d bytes.\n", blackbird_firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE);
+ if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) {
+ dprintk(0, "ERROR: Firmware size mismatch (have %ld, expected %d)\n",
+ firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE);
return -1;
}
- if ((blackbird_firmware->data[0] != 0xA7) ||
- (blackbird_firmware->data[1] != 0x0D) ||
- (blackbird_firmware->data[2] != 0x00) ||
- (blackbird_firmware->data[3] != 0x00) ||
- (blackbird_firmware->data[4] != 0x66) ||
- (blackbird_firmware->data[5] != 0xBB) ||
- (blackbird_firmware->data[6] != 0x55) ||
- (blackbird_firmware->data[7] != 0xAA)) {
- dprintk(0, "ERROR: Firmware is corrupt or not for an encoder chip\n");
+ if (0 != memcmp(firmware->data, magic, 8)) {
+ dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n");
return -1;
}
/* transfer to the chip */
- u32 checksum = 0;
- u32 *dataptr = (u32 *)blackbird_firmware->data;
- for (i = 0; i < (blackbird_firmware->size >> 2); i++) {
+ dprintk(1,"Loading firmware ...\n");
+ dataptr = (u32*)firmware->data;
+ for (i = 0; i < (firmware->size >> 2); i++) {
value = *dataptr;
checksum += ~value;
- memory_write(dev, i, value);
+ memory_write(dev->core, i, value);
dataptr++;
}
- release_firmware(blackbird_firmware);
-
- /* this takes a whole second, but it ensures the upload worked (maybe some hw needs other RAM timings, etc) */
/* read back to verify with the checksum */
for (i--; i >= 0; i--) {
- memory_read(dev, i, &value);
+ memory_read(dev->core, i, &value);
checksum -= ~value;
}
-
if (checksum) {
- dprintk(0, "ERROR: Firmware Upload Failed (memory checksums don't match).\n");
+ dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n");
return -1;
}
-
+ release_firmware(firmware);
dprintk(0, "Firmware upload successful.\n");
-#if 0
- for (i = 0; i < 1024; i+=4) {
- //u32 value;
- memory_read(dev, (i>>2), &value);
- if (0 == (i % 16))
- printk(KERN_INFO "cx88 fw: %02x:",i);
- printk(" %02x %02x %02x %02x",(value & 0xFF),((value>>8) & 0xFF),((value>>16) & 0xFF),((value>>24) & 0xFF));
- if (12 == (i % 16))
- printk("\n");
- }
-#endif
-
- retval |= register_write(dev, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
- retval |= register_read(dev, IVTV_REG_SPU, &value);
- retval |= register_write(dev, IVTV_REG_SPU, value & 0xFFFFFFFE);
-
- udelay(1000);
+ retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
+ retval |= register_read(dev->core, IVTV_REG_SPU, &value);
+ retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE);
+ msleep(1);
- retval |= register_read(dev, IVTV_REG_VPU, &value);
- retval |= register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8UL);
- //retval |= register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFFB);
+ retval |= register_read(dev->core, IVTV_REG_VPU, &value);
+ retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8);
- if (retval < 0) dprintk(0, "Error with register_write\n");
+ if (retval < 0)
+ dprintk(0, "Error with register_write\n");
return 0;
}
-void mpegport_codec_settings(struct cx8800_dev *dev)
+static void blackbird_codec_settings(struct cx8802_dev *dev)
{
+ int bitrate_mode = 1;
+ int bitrate = 7500000;
+ int bitrate_peak = 7500000;
+
/* assign stream type */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 0); /* program stream */
- //mpegport_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 2); /* MPEG1 stream */
- //mpegport_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 3); /* PES A/V */
- //mpegport_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 10); /* DVD stream */
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 0); /* program stream */
+ //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 2); /* MPEG1 stream */
+ //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 3); /* PES A/V */
+ //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 10); /* DVD stream */
/* assign output port */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_OUTPUT_PORT, 1, 0, 1); /* 1 = Host */
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_OUTPUT_PORT, 1, 0, 1); /* 1 = Host */
/* assign framerate */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_FRAMERATE, 1, 0, 0);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAMERATE, 1, 0, 0);
/* assign frame size */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_FRAME_SIZE, 2, 0, 480, 720);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_SIZE, 2, 0, 480, 720);
/* assign aspect ratio */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_ASPECT_RATIO, 1, 0, 2);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_ASPECT_RATIO, 1, 0, 2);
- int bitrate_mode = 1;
- int bitrate = 7500000;
- int bitrate_peak = 7500000;
/* assign bitrates */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_BITRATES, 5, 0,
- bitrate_mode, /* mode */
- bitrate, /* bps */
- bitrate_peak / 400, /* peak/400 */
- 0, 0x70); /* encoding buffer, ckennedy */
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_BITRATES, 5, 0,
+ bitrate_mode, /* mode */
+ bitrate, /* bps */
+ bitrate_peak / 400, /* peak/400 */
+ 0, 0x70); /* encoding buffer, ckennedy */
/* assign gop properties */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 15, 3);
- //mpegport_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 2, 1);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 15, 3);
+ //blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 2, 1);
/* assign 3 2 pulldown */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_3_2_PULLDOWN, 1, 0, 0);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_3_2_PULLDOWN, 1, 0, 0);
/* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4));
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4));
/* assign gop closure */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_GOP_CLOSURE, 1, 0, 0);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_CLOSURE, 1, 0, 0);
/* assign audio properties */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4));
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4));
/* assign dnr filter mode */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_MODE, 2, 0, 0, 0);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_MODE, 2, 0, 0, 0);
/* assign dnr filter props*/
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_PROPS, 2, 0, 0, 0);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_PROPS, 2, 0, 0, 0);
/* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_CORING_LEVELS, 4, 0, 0, 255, 0, 255);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_CORING_LEVELS, 4, 0, 0, 255, 0, 255);
/* assign spatial filter type: luma_t: 1 = horiz_only, chroma_t: 1 = horiz_only */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE, 2, 0, 1, 1);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE, 2, 0, 1, 1);
/* assign frame drop rate */
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0);
}
-int mpegport_initialize_codec(struct cx8800_dev *dev)
+static int blackbird_initialize_codec(struct cx8802_dev *dev)
{
+ struct cx88_core *core = dev->core;
+ int version;
int retval;
+
dprintk(1,"Initialize codec\n");
-
- retval = mpegport_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */
+ retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */
if (retval < 0) {
/* ping was not successful, reset and upload firmware */
-
cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
- udelay(300);
+ msleep(1);
cx_write(MO_SRST_IO, 1); /* SYS_RSTO=1 */
- udelay(100);
-
- retval = mpegport_load_firmware(dev);
- if (retval < 0) { dprintk(0, "Error with firmware load!\n"); return retval; }
-
- dev->mpegport_mailbox = mpegport_find_mailbox(dev);
- if (dev->mpegport_mailbox < 0) { dprintk(0, "Error with mailbox search!\n"); return dev->mpegport_mailbox; }
+ msleep(1);
+ retval = blackbird_load_firmware(dev);
+ if (retval < 0)
+ return retval;
+
+ dev->mailbox = blackbird_find_mailbox(dev);
+ if (dev->mailbox < 0)
+ return -1;
- retval = mpegport_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */
+ retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */
if (retval < 0) {
dprintk(0, "ERROR: Firmware ping failed!\n");
return -1;
}
- int firmware_version;
- retval = mpegport_api_cmd(dev, IVTV_API_ENC_GETVER, 0, 1, &firmware_version);
+ retval = blackbird_api_cmd(dev, IVTV_API_ENC_GETVER, 0, 1, &version);
if (retval < 0) {
dprintk(0, "ERROR: Firmware get encoder version failed!\n");
return -1;
}
- dprintk(0, "Encoder revision: 0x%08x\n", firmware_version);
-
- }
- else
- {
- dprintk(1, "Firmware already present and responding to ping (not reloading)\n");
+ dprintk(0, "Firmware version is 0x%08x\n", version);
}
-
- udelay(500);
+ msleep(1);
cx_write(MO_PINMUX_IO, 0x88); /* 656-8bit IO and enable MPEG parallel IO */
cx_clear(MO_INPUT_FORMAT, 0x100); /* chroma subcarrier lock to normal? */
cx_write(MO_VBOS_CONTROL, 0x84A00); /* no 656 mode, 8-bit pixels, disable VBI */
-
cx_clear(MO_OUTPUT_FORMAT, 0x0008); /* Normal Y-limits to let the mpeg encoder sync */
- /* this seems to be necessary, because otherwise the picture isn't always correct,
- even though I think the scaler in the cx23880 should not change the itu656 output.
- maybe it's a pll or something? */
+#if 0 /* FIXME */
set_scale(dev, 720, 480, V4L2_FIELD_INTERLACED);
+#endif
+ blackbird_codec_settings(dev);
+ msleep(1);
- udelay(500);
-
- mpegport_codec_settings(dev);
-
- //mpegport_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
- //mpegport_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180);
- mpegport_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ //blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
+ //blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- mpegport_api_cmd(dev, IVTV_API_INITIALIZE_INPUT, 0, 0); /* initialize the video input */
+ blackbird_api_cmd(dev, IVTV_API_INITIALIZE_INPUT, 0, 0); /* initialize the video input */
- udelay(500);
+ msleep(1);
- mpegport_api_cmd(dev, IVTV_API_MUTE_VIDEO, 1, 0, 0);
- udelay(500);
- mpegport_api_cmd(dev, IVTV_API_MUTE_AUDIO, 1, 0, 0);
- udelay(500);
-
- mpegport_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); /* start capturing to the host interface */
- //mpegport_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0); /* start capturing to the host interface */
+ blackbird_api_cmd(dev, IVTV_API_MUTE_VIDEO, 1, 0, 0);
+ msleep(1);
+ blackbird_api_cmd(dev, IVTV_API_MUTE_AUDIO, 1, 0, 0);
+ msleep(1);
- udelay(500);
+ blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); /* start capturing to the host interface */
+ //blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0); /* start capturing to the host interface */
+ msleep(1);
- mpegport_api_cmd(dev, IVTV_API_REFRESH_INPUT, 0,0);
- return retval;
+ blackbird_api_cmd(dev, IVTV_API_REFRESH_INPUT, 0,0);
+ return 0;
}
-#endif
+/* ------------------------------------------------------------------ */
+
+static int bb_buf_setup(struct file *file, unsigned int *count, unsigned int *size)
+{
+ struct cx8802_fh *fh = file->private_data;
+
+ fh->dev->ts_packet_size = 512;
+ fh->dev->ts_packet_count = 100;
+
+ *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
+ if (0 == *count)
+ *count = mpegbufs;
+ if (*count < 2)
+ *count = 2;
+ if (*count > 32)
+ *count = 32;
+ return 0;
+}
+
+static int
+bb_buf_prepare(struct file *file, struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ struct cx8802_fh *fh = file->private_data;
+ return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb);
+}
+
+static void
+bb_buf_queue(struct file *file, struct videobuf_buffer *vb)
+{
+ struct cx8802_fh *fh = file->private_data;
+ cx8802_buf_queue(fh->dev, (struct cx88_buffer*)vb);
+}
+
+static void bb_buf_release(struct file *file, struct videobuf_buffer *vb)
+{
+ struct cx8802_fh *fh = file->private_data;
+ cx88_free_buffer(fh->dev->pci, (struct cx88_buffer*)vb);
+}
+
+static struct videobuf_queue_ops blackbird_qops = {
+ .buf_setup = bb_buf_setup,
+ .buf_prepare = bb_buf_prepare,
+ .buf_queue = bb_buf_queue,
+ .buf_release = bb_buf_release,
+};
/* ------------------------------------------------------------------ */
@@ -587,13 +594,10 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *arg)
{
struct cx8802_fh *fh = file->private_data;
-
-#if 0
struct cx8802_dev *dev = fh->dev;
- if (mpeg_debug > 1)
+ if (debug > 1)
cx88_print_ioctl(dev->core->name,cmd);
-#endif
switch (cmd) {
@@ -670,16 +674,14 @@ static int mpeg_open(struct inode *inode, struct file *file)
list_for_each(list,&cx8802_devlist) {
h = list_entry(list, struct cx8802_dev, devlist);
if (h->mpeg_dev->minor == minor)
- dev = h;
+ dev = h;
}
if (NULL == dev)
return -ENODEV;
-#if 0 /* FIXME */
- if (mpegport_initialize_codec(dev) < 0)
+ if (blackbird_initialize_codec(dev) < 0)
return -EINVAL;
dprintk(1,"open minor=%d\n",minor);
-#endif
/* allocate + initialize per filehandle data */
fh = kmalloc(sizeof(*fh),GFP_KERNEL);
@@ -689,7 +691,7 @@ static int mpeg_open(struct inode *inode, struct file *file)
file->private_data = fh;
fh->dev = dev;
- videobuf_queue_init(&fh->mpegq, &cx8802_mpeg_qops,
+ videobuf_queue_init(&fh->mpegq, &blackbird_qops,
dev->pci, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_TOP,
@@ -703,9 +705,7 @@ static int mpeg_release(struct inode *inode, struct file *file)
{
struct cx8802_fh *fh = file->private_data;
-#if 0 /* FIXME */
- mpegport_api_cmd(fh->dev, IVTV_API_END_CAPTURE, 3, 0, 1, 0, 0x13);
-#endif
+ blackbird_api_cmd(fh->dev, IVTV_API_END_CAPTURE, 3, 0, 1, 0, 0x13);
/* stop mpeg capture */
if (fh->mpegq.streaming)
@@ -765,7 +765,7 @@ static struct video_device cx8802_mpeg_template =
/* ------------------------------------------------------------------ */
-static void cx8802_unregister_video(struct cx8802_dev *dev)
+static void blackbird_unregister_video(struct cx8802_dev *dev)
{
if (dev->mpeg_dev) {
if (-1 != dev->mpeg_dev->minor)
@@ -776,7 +776,7 @@ static void cx8802_unregister_video(struct cx8802_dev *dev)
}
}
-static int cx8802_register_video(struct cx8802_dev *dev)
+static int blackbird_register_video(struct cx8802_dev *dev)
{
int err;
@@ -792,10 +792,105 @@ static int cx8802_register_video(struct cx8802_dev *dev)
dev->core->name,dev->mpeg_dev->minor & 0x1f);
}
-#if 0
-module_init(cx8802_init);
-module_exit(cx8802_fini);
+/* ----------------------------------------------------------- */
+
+static int __devinit blackbird_probe(struct pci_dev *pci_dev,
+ const struct pci_device_id *pci_id)
+{
+ struct cx8802_dev *dev;
+ struct cx88_core *core;
+ int err;
+
+ /* general setup */
+ core = cx88_core_get(pci_dev);
+ if (NULL == core)
+ return -EINVAL;
+
+ err = -ENODEV;
+ if (!cx88_boards[core->board].blackbird)
+ goto fail_core;
+
+ err = -ENOMEM;
+ dev = kmalloc(sizeof(*dev),GFP_KERNEL);
+ if (NULL == dev)
+ goto fail_core;
+ memset(dev,0,sizeof(*dev));
+ dev->pci = pci_dev;
+ dev->core = core;
+
+ err = cx8802_init_common(dev);
+ if (0 != err)
+ goto fail_free;
+
+ /* blackbird stuff */
+ printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n",
+ core->name);
+ host_setup(dev->core);
+
+ list_add_tail(&dev->devlist,&cx8802_devlist);
+ blackbird_register_video(dev);
+ return 0;
+
+ fail_free:
+ kfree(dev);
+ fail_core:
+ cx88_core_put(core,pci_dev);
+ return err;
+}
+
+static void __devexit blackbird_remove(struct pci_dev *pci_dev)
+{
+ struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
+
+ /* blackbird */
+ blackbird_unregister_video(dev);
+ list_del(&dev->devlist);
+
+ /* common */
+ cx8802_fini_common(dev);
+ cx88_core_put(dev->core,dev->pci);
+ kfree(dev);
+}
+
+static struct pci_device_id cx8802_pci_tbl[] = {
+ {
+ .vendor = 0x14f1,
+ .device = 0x8802,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },{
+ /* --- end of list --- */
+ }
+};
+MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
+
+static struct pci_driver blackbird_pci_driver = {
+ .name = "cx8802",
+ .id_table = cx8802_pci_tbl,
+ .probe = blackbird_probe,
+ .remove = blackbird_remove,
+};
+
+static int blackbird_init(void)
+{
+ printk(KERN_INFO "cx2388x blackbird driver version %d.%d.%d loaded\n",
+ (CX88_VERSION_CODE >> 16) & 0xff,
+ (CX88_VERSION_CODE >> 8) & 0xff,
+ CX88_VERSION_CODE & 0xff);
+#ifdef SNAPSHOT
+ printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
+ SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
#endif
+ return pci_module_init(&blackbird_pci_driver);
+}
+
+static void blackbird_fini(void)
+{
+ pci_unregister_driver(&blackbird_pci_driver);
+}
+
+module_init(blackbird_init);
+module_exit(blackbird_fini);
/* ----------------------------------------------------------- */
/*