Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Support for a cx23416 mpeg encoder via cx2388x host port.
0004  *  "blackbird" reference design.
0005  *
0006  *    (c) 2004 Jelle Foks <jelle@foks.us>
0007  *    (c) 2004 Gerd Knorr <kraxel@bytesex.org>
0008  *
0009  *    (c) 2005-2006 Mauro Carvalho Chehab <mchehab@kernel.org>
0010  *        - video_ioctl2 conversion
0011  *
0012  *  Includes parts from the ivtv driver <http://sourceforge.net/projects/ivtv/>
0013  */
0014 
0015 #include "cx88.h"
0016 
0017 #include <linux/module.h>
0018 #include <linux/init.h>
0019 #include <linux/slab.h>
0020 #include <linux/fs.h>
0021 #include <linux/delay.h>
0022 #include <linux/device.h>
0023 #include <linux/firmware.h>
0024 #include <media/v4l2-common.h>
0025 #include <media/v4l2-ioctl.h>
0026 #include <media/v4l2-event.h>
0027 #include <media/drv-intf/cx2341x.h>
0028 
0029 MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards");
0030 MODULE_AUTHOR("Jelle Foks <jelle@foks.us>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
0031 MODULE_LICENSE("GPL v2");
0032 MODULE_VERSION(CX88_VERSION);
0033 
0034 static unsigned int debug;
0035 module_param(debug, int, 0644);
0036 MODULE_PARM_DESC(debug, "enable debug messages [blackbird]");
0037 
0038 #define dprintk(level, fmt, arg...) do {                \
0039     if (debug + 1 > level)                      \
0040         printk(KERN_DEBUG pr_fmt("%s: blackbird:" fmt),     \
0041             __func__, ##arg);               \
0042 } while (0)
0043 
0044 /* ------------------------------------------------------------------ */
0045 
0046 #define BLACKBIRD_FIRM_IMAGE_SIZE 376836
0047 
0048 /* defines below are from ivtv-driver.h */
0049 
0050 #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
0051 
0052 /* Firmware API commands */
0053 #define IVTV_API_STD_TIMEOUT 500
0054 
0055 enum blackbird_capture_type {
0056     BLACKBIRD_MPEG_CAPTURE,
0057     BLACKBIRD_RAW_CAPTURE,
0058     BLACKBIRD_RAW_PASSTHRU_CAPTURE
0059 };
0060 
0061 enum blackbird_capture_bits {
0062     BLACKBIRD_RAW_BITS_NONE             = 0x00,
0063     BLACKBIRD_RAW_BITS_YUV_CAPTURE      = 0x01,
0064     BLACKBIRD_RAW_BITS_PCM_CAPTURE      = 0x02,
0065     BLACKBIRD_RAW_BITS_VBI_CAPTURE      = 0x04,
0066     BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08,
0067     BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE  = 0x10
0068 };
0069 
0070 enum blackbird_capture_end {
0071     BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */
0072     BLACKBIRD_END_NOW, /* stop immediately, no irq */
0073 };
0074 
0075 enum blackbird_framerate {
0076     BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */
0077     BLACKBIRD_FRAMERATE_PAL_25   /* PAL: 25fps */
0078 };
0079 
0080 enum blackbird_stream_port {
0081     BLACKBIRD_OUTPUT_PORT_MEMORY,
0082     BLACKBIRD_OUTPUT_PORT_STREAMING,
0083     BLACKBIRD_OUTPUT_PORT_SERIAL
0084 };
0085 
0086 enum blackbird_data_xfer_status {
0087     BLACKBIRD_MORE_BUFFERS_FOLLOW,
0088     BLACKBIRD_LAST_BUFFER,
0089 };
0090 
0091 enum blackbird_picture_mask {
0092     BLACKBIRD_PICTURE_MASK_NONE,
0093     BLACKBIRD_PICTURE_MASK_I_FRAMES,
0094     BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3,
0095     BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7,
0096 };
0097 
0098 enum blackbird_vbi_mode_bits {
0099     BLACKBIRD_VBI_BITS_SLICED,
0100     BLACKBIRD_VBI_BITS_RAW,
0101 };
0102 
0103 enum blackbird_vbi_insertion_bits {
0104     BLACKBIRD_VBI_BITS_INSERT_IN_XTENSION_USR_DATA,
0105     BLACKBIRD_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1,
0106     BLACKBIRD_VBI_BITS_SEPARATE_STREAM = 0x2 << 1,
0107     BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1,
0108     BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1,
0109 };
0110 
0111 enum blackbird_dma_unit {
0112     BLACKBIRD_DMA_BYTES,
0113     BLACKBIRD_DMA_FRAMES,
0114 };
0115 
0116 enum blackbird_dma_transfer_status_bits {
0117     BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01,
0118     BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04,
0119     BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10,
0120 };
0121 
0122 enum blackbird_pause {
0123     BLACKBIRD_PAUSE_ENCODING,
0124     BLACKBIRD_RESUME_ENCODING,
0125 };
0126 
0127 enum blackbird_copyright {
0128     BLACKBIRD_COPYRIGHT_OFF,
0129     BLACKBIRD_COPYRIGHT_ON,
0130 };
0131 
0132 enum blackbird_notification_type {
0133     BLACKBIRD_NOTIFICATION_REFRESH,
0134 };
0135 
0136 enum blackbird_notification_status {
0137     BLACKBIRD_NOTIFICATION_OFF,
0138     BLACKBIRD_NOTIFICATION_ON,
0139 };
0140 
0141 enum blackbird_notification_mailbox {
0142     BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1,
0143 };
0144 
0145 enum blackbird_field1_lines {
0146     BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */
0147     BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */
0148     BLACKBIRD_FIELD1_MICRONAS = 0x0105, /* 261 */
0149 };
0150 
0151 enum blackbird_field2_lines {
0152     BLACKBIRD_FIELD2_SAA7114 = 0x00EF, /* 239 */
0153     BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */
0154     BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */
0155 };
0156 
0157 enum blackbird_custom_data_type {
0158     BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
0159     BLACKBIRD_CUSTOM_PRIVATE_PACKET,
0160 };
0161 
0162 enum blackbird_mute {
0163     BLACKBIRD_UNMUTE,
0164     BLACKBIRD_MUTE,
0165 };
0166 
0167 enum blackbird_mute_video_mask {
0168     BLACKBIRD_MUTE_VIDEO_V_MASK = 0x0000FF00,
0169     BLACKBIRD_MUTE_VIDEO_U_MASK = 0x00FF0000,
0170     BLACKBIRD_MUTE_VIDEO_Y_MASK = 0xFF000000,
0171 };
0172 
0173 enum blackbird_mute_video_shift {
0174     BLACKBIRD_MUTE_VIDEO_V_SHIFT = 8,
0175     BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16,
0176     BLACKBIRD_MUTE_VIDEO_Y_SHIFT = 24,
0177 };
0178 
0179 /* Registers */
0180 #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/)
0181 #define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC /*| IVTV_REG_OFFSET*/)
0182 #define IVTV_REG_SPU (0x9050 /*| IVTV_REG_OFFSET*/)
0183 #define IVTV_REG_HW_BLOCKS (0x9054 /*| IVTV_REG_OFFSET*/)
0184 #define IVTV_REG_VPU (0x9058 /*| IVTV_REG_OFFSET*/)
0185 #define IVTV_REG_APU (0xA064 /*| IVTV_REG_OFFSET*/)
0186 
0187 /* ------------------------------------------------------------------ */
0188 
0189 static void host_setup(struct cx88_core *core)
0190 {
0191     /* toggle reset of the host */
0192     cx_write(MO_GPHST_SOFT_RST, 1);
0193     udelay(100);
0194     cx_write(MO_GPHST_SOFT_RST, 0);
0195     udelay(100);
0196 
0197     /* host port setup */
0198     cx_write(MO_GPHST_WSC, 0x44444444U);
0199     cx_write(MO_GPHST_XFR, 0);
0200     cx_write(MO_GPHST_WDTH, 15);
0201     cx_write(MO_GPHST_HDSHK, 0);
0202     cx_write(MO_GPHST_MUX16, 0x44448888U);
0203     cx_write(MO_GPHST_MODE, 0);
0204 }
0205 
0206 /* ------------------------------------------------------------------ */
0207 
0208 #define P1_MDATA0 0x390000
0209 #define P1_MDATA1 0x390001
0210 #define P1_MDATA2 0x390002
0211 #define P1_MDATA3 0x390003
0212 #define P1_MADDR2 0x390004
0213 #define P1_MADDR1 0x390005
0214 #define P1_MADDR0 0x390006
0215 #define P1_RDATA0 0x390008
0216 #define P1_RDATA1 0x390009
0217 #define P1_RDATA2 0x39000A
0218 #define P1_RDATA3 0x39000B
0219 #define P1_RADDR0 0x39000C
0220 #define P1_RADDR1 0x39000D
0221 #define P1_RRDWR  0x39000E
0222 
0223 static int wait_ready_gpio0_bit1(struct cx88_core *core, u32 state)
0224 {
0225     unsigned long timeout = jiffies + msecs_to_jiffies(1);
0226     u32 gpio0, need;
0227 
0228     need = state ? 2 : 0;
0229     for (;;) {
0230         gpio0 = cx_read(MO_GP0_IO) & 2;
0231         if (need == gpio0)
0232             return 0;
0233         if (time_after(jiffies, timeout))
0234             return -1;
0235         udelay(1);
0236     }
0237 }
0238 
0239 static int memory_write(struct cx88_core *core, u32 address, u32 value)
0240 {
0241     /* Warning: address is dword address (4 bytes) */
0242     cx_writeb(P1_MDATA0, (unsigned int)value);
0243     cx_writeb(P1_MDATA1, (unsigned int)(value >> 8));
0244     cx_writeb(P1_MDATA2, (unsigned int)(value >> 16));
0245     cx_writeb(P1_MDATA3, (unsigned int)(value >> 24));
0246     cx_writeb(P1_MADDR2, (unsigned int)(address >> 16) | 0x40);
0247     cx_writeb(P1_MADDR1, (unsigned int)(address >> 8));
0248     cx_writeb(P1_MADDR0, (unsigned int)address);
0249     cx_read(P1_MDATA0);
0250     cx_read(P1_MADDR0);
0251 
0252     return wait_ready_gpio0_bit1(core, 1);
0253 }
0254 
0255 static int memory_read(struct cx88_core *core, u32 address, u32 *value)
0256 {
0257     int retval;
0258     u32 val;
0259 
0260     /* Warning: address is dword address (4 bytes) */
0261     cx_writeb(P1_MADDR2, (unsigned int)(address >> 16) & ~0xC0);
0262     cx_writeb(P1_MADDR1, (unsigned int)(address >> 8));
0263     cx_writeb(P1_MADDR0, (unsigned int)address);
0264     cx_read(P1_MADDR0);
0265 
0266     retval = wait_ready_gpio0_bit1(core, 1);
0267 
0268     cx_writeb(P1_MDATA3, 0);
0269     val     = (unsigned char)cx_read(P1_MDATA3) << 24;
0270     cx_writeb(P1_MDATA2, 0);
0271     val    |= (unsigned char)cx_read(P1_MDATA2) << 16;
0272     cx_writeb(P1_MDATA1, 0);
0273     val    |= (unsigned char)cx_read(P1_MDATA1) << 8;
0274     cx_writeb(P1_MDATA0, 0);
0275     val    |= (unsigned char)cx_read(P1_MDATA0);
0276 
0277     *value  = val;
0278     return retval;
0279 }
0280 
0281 static int register_write(struct cx88_core *core, u32 address, u32 value)
0282 {
0283     cx_writeb(P1_RDATA0, (unsigned int)value);
0284     cx_writeb(P1_RDATA1, (unsigned int)(value >> 8));
0285     cx_writeb(P1_RDATA2, (unsigned int)(value >> 16));
0286     cx_writeb(P1_RDATA3, (unsigned int)(value >> 24));
0287     cx_writeb(P1_RADDR0, (unsigned int)address);
0288     cx_writeb(P1_RADDR1, (unsigned int)(address >> 8));
0289     cx_writeb(P1_RRDWR, 1);
0290     cx_read(P1_RDATA0);
0291     cx_read(P1_RADDR0);
0292 
0293     return wait_ready_gpio0_bit1(core, 1);
0294 }
0295 
0296 static int register_read(struct cx88_core *core, u32 address, u32 *value)
0297 {
0298     int retval;
0299     u32 val;
0300 
0301     cx_writeb(P1_RADDR0, (unsigned int)address);
0302     cx_writeb(P1_RADDR1, (unsigned int)(address >> 8));
0303     cx_writeb(P1_RRDWR, 0);
0304     cx_read(P1_RADDR0);
0305 
0306     retval  = wait_ready_gpio0_bit1(core, 1);
0307     val     = (unsigned char)cx_read(P1_RDATA0);
0308     val    |= (unsigned char)cx_read(P1_RDATA1) << 8;
0309     val    |= (unsigned char)cx_read(P1_RDATA2) << 16;
0310     val    |= (unsigned char)cx_read(P1_RDATA3) << 24;
0311 
0312     *value  = val;
0313     return retval;
0314 }
0315 
0316 /* ------------------------------------------------------------------ */
0317 
0318 static int blackbird_mbox_func(void *priv, u32 command, int in,
0319                    int out, u32 data[CX2341X_MBOX_MAX_DATA])
0320 {
0321     struct cx8802_dev *dev = priv;
0322     unsigned long timeout;
0323     u32 value, flag, retval;
0324     int i;
0325 
0326     dprintk(1, "%s: 0x%X\n", __func__, command);
0327 
0328     /*
0329      * this may not be 100% safe if we can't read any memory location
0330      * without side effects
0331      */
0332     memory_read(dev->core, dev->mailbox - 4, &value);
0333     if (value != 0x12345678) {
0334         dprintk(0,
0335             "Firmware and/or mailbox pointer not initialized or corrupted\n");
0336         return -EIO;
0337     }
0338 
0339     memory_read(dev->core, dev->mailbox, &flag);
0340     if (flag) {
0341         dprintk(0, "ERROR: Mailbox appears to be in use (%x)\n", flag);
0342         return -EIO;
0343     }
0344 
0345     flag |= 1; /* tell 'em we're working on it */
0346     memory_write(dev->core, dev->mailbox, flag);
0347 
0348     /* write command + args + fill remaining with zeros */
0349     memory_write(dev->core, dev->mailbox + 1, command); /* command code */
0350     /* timeout */
0351     memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT);
0352     for (i = 0; i < in; i++) {
0353         memory_write(dev->core, dev->mailbox + 4 + i, data[i]);
0354         dprintk(1, "API Input %d = %d\n", i, data[i]);
0355     }
0356     for (; i < CX2341X_MBOX_MAX_DATA; i++)
0357         memory_write(dev->core, dev->mailbox + 4 + i, 0);
0358 
0359     flag |= 3; /* tell 'em we're done writing */
0360     memory_write(dev->core, dev->mailbox, flag);
0361 
0362     /* wait for firmware to handle the API command */
0363     timeout = jiffies + msecs_to_jiffies(1000);
0364     for (;;) {
0365         memory_read(dev->core, dev->mailbox, &flag);
0366         if (0 != (flag & 4))
0367             break;
0368         if (time_after(jiffies, timeout)) {
0369             dprintk(0, "ERROR: API Mailbox timeout %x\n", command);
0370             return -EIO;
0371         }
0372         udelay(10);
0373     }
0374 
0375     /* read output values */
0376     for (i = 0; i < out; i++) {
0377         memory_read(dev->core, dev->mailbox + 4 + i, data + i);
0378         dprintk(1, "API Output %d = %d\n", i, data[i]);
0379     }
0380 
0381     memory_read(dev->core, dev->mailbox + 2, &retval);
0382     dprintk(1, "API result = %d\n", retval);
0383 
0384     flag = 0;
0385     memory_write(dev->core, dev->mailbox, flag);
0386     return retval;
0387 }
0388 
0389 /* ------------------------------------------------------------------ */
0390 
0391 /*
0392  * We don't need to call the API often, so using just one mailbox
0393  * will probably suffice
0394  */
0395 static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command,
0396                  u32 inputcnt, u32 outputcnt, ...)
0397 {
0398     u32 data[CX2341X_MBOX_MAX_DATA];
0399     va_list vargs;
0400     int i, err;
0401 
0402     va_start(vargs, outputcnt);
0403 
0404     for (i = 0; i < inputcnt; i++)
0405         data[i] = va_arg(vargs, int);
0406 
0407     err = blackbird_mbox_func(dev, command, inputcnt, outputcnt, data);
0408     for (i = 0; i < outputcnt; i++) {
0409         int *vptr = va_arg(vargs, int *);
0410         *vptr = data[i];
0411     }
0412     va_end(vargs);
0413     return err;
0414 }
0415 
0416 static int blackbird_find_mailbox(struct cx8802_dev *dev)
0417 {
0418     u32 signature[4] = {0x12345678, 0x34567812, 0x56781234, 0x78123456};
0419     int signaturecnt = 0;
0420     u32 value;
0421     int i;
0422 
0423     for (i = 0; i < BLACKBIRD_FIRM_IMAGE_SIZE; i++) {
0424         memory_read(dev->core, i, &value);
0425         if (value == signature[signaturecnt])
0426             signaturecnt++;
0427         else
0428             signaturecnt = 0;
0429         if (signaturecnt == 4) {
0430             dprintk(1, "Mailbox signature found\n");
0431             return i + 1;
0432         }
0433     }
0434     dprintk(0, "Mailbox signature values not found!\n");
0435     return -EIO;
0436 }
0437 
0438 static int blackbird_load_firmware(struct cx8802_dev *dev)
0439 {
0440     static const unsigned char magic[8] = {
0441         0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
0442     };
0443     const struct firmware *firmware;
0444     int i, retval = 0;
0445     u32 value = 0;
0446     u32 checksum = 0;
0447     __le32 *dataptr;
0448 
0449     retval  = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED);
0450     retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS,
0451                  IVTV_CMD_HW_BLOCKS_RST);
0452     retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH,
0453                  0x80000640);
0454     retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE,
0455                  0x1A);
0456     usleep_range(10000, 20000);
0457     retval |= register_write(dev->core, IVTV_REG_APU, 0);
0458 
0459     if (retval < 0)
0460         dprintk(0, "Error with register_write\n");
0461 
0462     retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME,
0463                   &dev->pci->dev);
0464 
0465     if (retval != 0) {
0466         pr_err("Hotplug firmware request failed (%s).\n",
0467                CX2341X_FIRM_ENC_FILENAME);
0468         pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n");
0469         return -EIO;
0470     }
0471 
0472     if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) {
0473         pr_err("Firmware size mismatch (have %zd, expected %d)\n",
0474                firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE);
0475         release_firmware(firmware);
0476         return -EINVAL;
0477     }
0478 
0479     if (memcmp(firmware->data, magic, 8) != 0) {
0480         pr_err("Firmware magic mismatch, wrong file?\n");
0481         release_firmware(firmware);
0482         return -EINVAL;
0483     }
0484 
0485     /* transfer to the chip */
0486     dprintk(1, "Loading firmware ...\n");
0487     dataptr = (__le32 *)firmware->data;
0488     for (i = 0; i < (firmware->size >> 2); i++) {
0489         value = le32_to_cpu(*dataptr);
0490         checksum += ~value;
0491         memory_write(dev->core, i, value);
0492         dataptr++;
0493     }
0494 
0495     /* read back to verify with the checksum */
0496     for (i--; i >= 0; i--) {
0497         memory_read(dev->core, i, &value);
0498         checksum -= ~value;
0499     }
0500     release_firmware(firmware);
0501     if (checksum) {
0502         pr_err("Firmware load might have failed (checksum mismatch).\n");
0503         return -EIO;
0504     }
0505     dprintk(0, "Firmware upload successful.\n");
0506 
0507     retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS,
0508                  IVTV_CMD_HW_BLOCKS_RST);
0509     retval |= register_read(dev->core, IVTV_REG_SPU, &value);
0510     retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE);
0511     usleep_range(10000, 20000);
0512 
0513     retval |= register_read(dev->core, IVTV_REG_VPU, &value);
0514     retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8);
0515 
0516     if (retval < 0)
0517         dprintk(0, "Error with register_write\n");
0518     return 0;
0519 }
0520 
0521 /*
0522  * Settings used by the windows tv app for PVR2000:
0523  * =================================================================================================================
0524  * Profile | Codec | Resolution | CBR/VBR | Video Qlty   | V. Bitrate | Frmrate | Audio Codec | A. Bitrate | A. Mode
0525  * -----------------------------------------------------------------------------------------------------------------
0526  * MPEG-1  | MPEG1 | 352x288PAL | (CBR)   | 1000:Optimal | 2000 Kbps  | 25fps   | MPG1 Layer2 | 224kbps    | Stereo
0527  * MPEG-2  | MPEG2 | 720x576PAL | VBR     | 600 :Good    | 4000 Kbps  | 25fps   | MPG1 Layer2 | 224kbps    | Stereo
0528  * VCD     | MPEG1 | 352x288PAL | (CBR)   | 1000:Optimal | 1150 Kbps  | 25fps   | MPG1 Layer2 | 224kbps    | Stereo
0529  * DVD     | MPEG2 | 720x576PAL | VBR     | 600 :Good    | 6000 Kbps  | 25fps   | MPG1 Layer2 | 224kbps    | Stereo
0530  * DB* DVD | MPEG2 | 720x576PAL | CBR     | 600 :Good    | 6000 Kbps  | 25fps   | MPG1 Layer2 | 224kbps    | Stereo
0531  * =================================================================================================================
0532  * [*] DB: "DirectBurn"
0533  */
0534 
0535 static void blackbird_codec_settings(struct cx8802_dev *dev)
0536 {
0537     struct cx88_core *core = dev->core;
0538 
0539     /* assign frame size */
0540     blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
0541               core->height, core->width);
0542 
0543     dev->cxhdl.width = core->width;
0544     dev->cxhdl.height = core->height;
0545     cx2341x_handler_set_50hz(&dev->cxhdl,
0546                  dev->core->tvnorm & V4L2_STD_625_50);
0547     cx2341x_handler_setup(&dev->cxhdl);
0548 }
0549 
0550 static int blackbird_initialize_codec(struct cx8802_dev *dev)
0551 {
0552     struct cx88_core *core = dev->core;
0553     int version;
0554     int retval;
0555 
0556     dprintk(1, "Initialize codec\n");
0557     retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
0558     if (retval < 0) {
0559         /* ping was not successful, reset and upload firmware */
0560         cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
0561         cx_write(MO_SRST_IO, 1); /* SYS_RSTO=1 */
0562         retval = blackbird_load_firmware(dev);
0563         if (retval < 0)
0564             return retval;
0565 
0566         retval = blackbird_find_mailbox(dev);
0567         if (retval < 0)
0568             return -1;
0569 
0570         dev->mailbox = retval;
0571 
0572         /* ping */
0573         retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0);
0574         if (retval < 0) {
0575             dprintk(0, "ERROR: Firmware ping failed!\n");
0576             return -1;
0577         }
0578 
0579         retval = blackbird_api_cmd(dev, CX2341X_ENC_GET_VERSION,
0580                        0, 1, &version);
0581         if (retval < 0) {
0582             dprintk(0,
0583                 "ERROR: Firmware get encoder version failed!\n");
0584             return -1;
0585         }
0586         dprintk(0, "Firmware version is 0x%08x\n", version);
0587     }
0588 
0589     cx_write(MO_PINMUX_IO, 0x88); /* 656-8bit IO and enable MPEG parallel IO */
0590     cx_clear(MO_INPUT_FORMAT, 0x100); /* chroma subcarrier lock to normal? */
0591     cx_write(MO_VBOS_CONTROL, 0x84A00); /* no 656 mode, 8-bit pixels, disable VBI */
0592     cx_clear(MO_OUTPUT_FORMAT, 0x0008); /* Normal Y-limits to let the mpeg encoder sync */
0593 
0594     blackbird_codec_settings(dev);
0595 
0596     blackbird_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0,
0597               BLACKBIRD_FIELD1_SAA7115, BLACKBIRD_FIELD2_SAA7115);
0598 
0599     blackbird_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0,
0600               BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
0601               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
0602 
0603     return 0;
0604 }
0605 
0606 static int blackbird_start_codec(struct cx8802_dev *dev)
0607 {
0608     struct cx88_core *core = dev->core;
0609     /* start capturing to the host interface */
0610     u32 reg;
0611 
0612     int i;
0613     int lastchange = -1;
0614     int lastval = 0;
0615 
0616     for (i = 0; (i < 10) && (i < (lastchange + 4)); i++) {
0617         reg = cx_read(AUD_STATUS);
0618 
0619         dprintk(1, "AUD_STATUS:%dL: 0x%x\n", i, reg);
0620         if ((reg & 0x0F) != lastval) {
0621             lastval = reg & 0x0F;
0622             lastchange = i;
0623         }
0624         msleep(100);
0625     }
0626 
0627     /* unmute audio source */
0628     cx_clear(AUD_VOL_CTL, (1 << 6));
0629 
0630     blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0, 0);
0631 
0632     /* initialize the video input */
0633     blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
0634 
0635     cx2341x_handler_set_busy(&dev->cxhdl, 1);
0636 
0637     /* start capturing to the host interface */
0638     blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,
0639               BLACKBIRD_MPEG_CAPTURE, BLACKBIRD_RAW_BITS_NONE);
0640 
0641     return 0;
0642 }
0643 
0644 static int blackbird_stop_codec(struct cx8802_dev *dev)
0645 {
0646     blackbird_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
0647               BLACKBIRD_END_NOW,
0648               BLACKBIRD_MPEG_CAPTURE,
0649               BLACKBIRD_RAW_BITS_NONE);
0650 
0651     cx2341x_handler_set_busy(&dev->cxhdl, 0);
0652 
0653     return 0;
0654 }
0655 
0656 /* ------------------------------------------------------------------ */
0657 
0658 static int queue_setup(struct vb2_queue *q,
0659                unsigned int *num_buffers, unsigned int *num_planes,
0660                unsigned int sizes[], struct device *alloc_devs[])
0661 {
0662     struct cx8802_dev *dev = q->drv_priv;
0663 
0664     *num_planes = 1;
0665     dev->ts_packet_size  = 188 * 4;
0666     dev->ts_packet_count  = 32;
0667     sizes[0] = dev->ts_packet_size * dev->ts_packet_count;
0668     return 0;
0669 }
0670 
0671 static int buffer_prepare(struct vb2_buffer *vb)
0672 {
0673     struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
0674     struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
0675     struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
0676 
0677     return cx8802_buf_prepare(vb->vb2_queue, dev, buf);
0678 }
0679 
0680 static void buffer_finish(struct vb2_buffer *vb)
0681 {
0682     struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
0683     struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
0684     struct cx88_buffer *buf = container_of(vbuf, struct cx88_buffer, vb);
0685     struct cx88_riscmem *risc = &buf->risc;
0686 
0687     if (risc->cpu)
0688         dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu,
0689                   risc->dma);
0690     memset(risc, 0, sizeof(*risc));
0691 }
0692 
0693 static void buffer_queue(struct vb2_buffer *vb)
0694 {
0695     struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
0696     struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
0697     struct cx88_buffer    *buf = container_of(vbuf, struct cx88_buffer, vb);
0698 
0699     cx8802_buf_queue(dev, buf);
0700 }
0701 
0702 static int start_streaming(struct vb2_queue *q, unsigned int count)
0703 {
0704     struct cx8802_dev *dev = q->drv_priv;
0705     struct cx88_dmaqueue *dmaq = &dev->mpegq;
0706     struct cx8802_driver *drv;
0707     struct cx88_buffer *buf;
0708     unsigned long flags;
0709     int err;
0710 
0711     /* Make sure we can acquire the hardware */
0712     drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
0713     if (!drv) {
0714         dprintk(1, "%s: blackbird driver is not loaded\n", __func__);
0715         err = -ENODEV;
0716         goto fail;
0717     }
0718 
0719     err = drv->request_acquire(drv);
0720     if (err != 0) {
0721         dprintk(1, "%s: Unable to acquire hardware, %d\n", __func__,
0722             err);
0723         goto fail;
0724     }
0725 
0726     if (blackbird_initialize_codec(dev) < 0) {
0727         drv->request_release(drv);
0728         err = -EINVAL;
0729         goto fail;
0730     }
0731 
0732     err = blackbird_start_codec(dev);
0733     if (err == 0) {
0734         buf = list_entry(dmaq->active.next, struct cx88_buffer, list);
0735         cx8802_start_dma(dev, dmaq, buf);
0736         return 0;
0737     }
0738 
0739 fail:
0740     spin_lock_irqsave(&dev->slock, flags);
0741     while (!list_empty(&dmaq->active)) {
0742         struct cx88_buffer *buf = list_entry(dmaq->active.next,
0743             struct cx88_buffer, list);
0744 
0745         list_del(&buf->list);
0746         vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
0747     }
0748     spin_unlock_irqrestore(&dev->slock, flags);
0749     return err;
0750 }
0751 
0752 static void stop_streaming(struct vb2_queue *q)
0753 {
0754     struct cx8802_dev *dev = q->drv_priv;
0755     struct cx88_dmaqueue *dmaq = &dev->mpegq;
0756     struct cx8802_driver *drv = NULL;
0757     unsigned long flags;
0758 
0759     cx8802_cancel_buffers(dev);
0760     blackbird_stop_codec(dev);
0761 
0762     /* Make sure we release the hardware */
0763     drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
0764     WARN_ON(!drv);
0765     if (drv)
0766         drv->request_release(drv);
0767 
0768     spin_lock_irqsave(&dev->slock, flags);
0769     while (!list_empty(&dmaq->active)) {
0770         struct cx88_buffer *buf = list_entry(dmaq->active.next,
0771             struct cx88_buffer, list);
0772 
0773         list_del(&buf->list);
0774         vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
0775     }
0776     spin_unlock_irqrestore(&dev->slock, flags);
0777 }
0778 
0779 static const struct vb2_ops blackbird_qops = {
0780     .queue_setup    = queue_setup,
0781     .buf_prepare  = buffer_prepare,
0782     .buf_finish = buffer_finish,
0783     .buf_queue    = buffer_queue,
0784     .wait_prepare = vb2_ops_wait_prepare,
0785     .wait_finish = vb2_ops_wait_finish,
0786     .start_streaming = start_streaming,
0787     .stop_streaming = stop_streaming,
0788 };
0789 
0790 /* ------------------------------------------------------------------ */
0791 
0792 static int vidioc_querycap(struct file *file, void  *priv,
0793                struct v4l2_capability *cap)
0794 {
0795     struct cx8802_dev *dev = video_drvdata(file);
0796     struct cx88_core *core = dev->core;
0797 
0798     strscpy(cap->driver, "cx88_blackbird", sizeof(cap->driver));
0799     return cx88_querycap(file, core, cap);
0800 }
0801 
0802 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
0803                    struct v4l2_fmtdesc *f)
0804 {
0805     if (f->index != 0)
0806         return -EINVAL;
0807 
0808     f->pixelformat = V4L2_PIX_FMT_MPEG;
0809     return 0;
0810 }
0811 
0812 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
0813                 struct v4l2_format *f)
0814 {
0815     struct cx8802_dev *dev = video_drvdata(file);
0816     struct cx88_core *core = dev->core;
0817 
0818     f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
0819     f->fmt.pix.bytesperline = 0;
0820     f->fmt.pix.sizeimage    = dev->ts_packet_size * dev->ts_packet_count;
0821     f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
0822     f->fmt.pix.width        = core->width;
0823     f->fmt.pix.height       = core->height;
0824     f->fmt.pix.field        = core->field;
0825     return 0;
0826 }
0827 
0828 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
0829                   struct v4l2_format *f)
0830 {
0831     struct cx8802_dev *dev = video_drvdata(file);
0832     struct cx88_core *core = dev->core;
0833     unsigned int maxw, maxh;
0834     enum v4l2_field field;
0835 
0836     f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
0837     f->fmt.pix.bytesperline = 0;
0838     f->fmt.pix.sizeimage    = dev->ts_packet_size * dev->ts_packet_count;
0839     f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
0840 
0841     maxw = norm_maxw(core->tvnorm);
0842     maxh = norm_maxh(core->tvnorm);
0843 
0844     field = f->fmt.pix.field;
0845 
0846     switch (field) {
0847     case V4L2_FIELD_TOP:
0848     case V4L2_FIELD_BOTTOM:
0849     case V4L2_FIELD_INTERLACED:
0850     case V4L2_FIELD_SEQ_BT:
0851     case V4L2_FIELD_SEQ_TB:
0852         break;
0853     default:
0854         field = (f->fmt.pix.height > maxh / 2)
0855             ? V4L2_FIELD_INTERLACED
0856             : V4L2_FIELD_BOTTOM;
0857         break;
0858     }
0859     if (V4L2_FIELD_HAS_T_OR_B(field))
0860         maxh /= 2;
0861 
0862     v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
0863                   &f->fmt.pix.height, 32, maxh, 0, 0);
0864     f->fmt.pix.field = field;
0865     return 0;
0866 }
0867 
0868 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
0869                 struct v4l2_format *f)
0870 {
0871     struct cx8802_dev *dev = video_drvdata(file);
0872     struct cx88_core  *core = dev->core;
0873 
0874     if (vb2_is_busy(&dev->vb2_mpegq))
0875         return -EBUSY;
0876     if (core->v4ldev && (vb2_is_busy(&core->v4ldev->vb2_vidq) ||
0877                  vb2_is_busy(&core->v4ldev->vb2_vbiq)))
0878         return -EBUSY;
0879     vidioc_try_fmt_vid_cap(file, priv, f);
0880     core->width = f->fmt.pix.width;
0881     core->height = f->fmt.pix.height;
0882     core->field = f->fmt.pix.field;
0883     cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height,
0884                f->fmt.pix.field);
0885     blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
0886               f->fmt.pix.height, f->fmt.pix.width);
0887     return 0;
0888 }
0889 
0890 static int vidioc_s_frequency(struct file *file, void *priv,
0891                   const struct v4l2_frequency *f)
0892 {
0893     struct cx8802_dev *dev = video_drvdata(file);
0894     struct cx88_core *core = dev->core;
0895     bool streaming;
0896 
0897     if (unlikely(core->board.tuner_type == UNSET))
0898         return -EINVAL;
0899     if (unlikely(f->tuner != 0))
0900         return -EINVAL;
0901     streaming = vb2_start_streaming_called(&dev->vb2_mpegq);
0902     if (streaming)
0903         blackbird_stop_codec(dev);
0904 
0905     cx88_set_freq(core, f);
0906     blackbird_initialize_codec(dev);
0907     cx88_set_scale(core, core->width, core->height, core->field);
0908     if (streaming)
0909         blackbird_start_codec(dev);
0910     return 0;
0911 }
0912 
0913 static int vidioc_log_status(struct file *file, void *priv)
0914 {
0915     struct cx8802_dev *dev = video_drvdata(file);
0916     struct cx88_core *core = dev->core;
0917     char name[32 + 2];
0918 
0919     snprintf(name, sizeof(name), "%s/2", core->name);
0920     call_all(core, core, log_status);
0921     v4l2_ctrl_handler_log_status(&dev->cxhdl.hdl, name);
0922     return 0;
0923 }
0924 
0925 static int vidioc_enum_input(struct file *file, void *priv,
0926                  struct v4l2_input *i)
0927 {
0928     struct cx8802_dev *dev = video_drvdata(file);
0929     struct cx88_core *core = dev->core;
0930 
0931     return cx88_enum_input(core, i);
0932 }
0933 
0934 static int vidioc_g_frequency(struct file *file, void *priv,
0935                   struct v4l2_frequency *f)
0936 {
0937     struct cx8802_dev *dev = video_drvdata(file);
0938     struct cx88_core *core = dev->core;
0939 
0940     if (unlikely(core->board.tuner_type == UNSET))
0941         return -EINVAL;
0942     if (unlikely(f->tuner != 0))
0943         return -EINVAL;
0944 
0945     f->frequency = core->freq;
0946     call_all(core, tuner, g_frequency, f);
0947 
0948     return 0;
0949 }
0950 
0951 static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
0952 {
0953     struct cx8802_dev *dev = video_drvdata(file);
0954     struct cx88_core *core = dev->core;
0955 
0956     *i = core->input;
0957     return 0;
0958 }
0959 
0960 static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
0961 {
0962     struct cx8802_dev *dev = video_drvdata(file);
0963     struct cx88_core *core = dev->core;
0964 
0965     if (i >= 4)
0966         return -EINVAL;
0967     if (!INPUT(i).type)
0968         return -EINVAL;
0969 
0970     cx88_newstation(core);
0971     cx88_video_mux(core, i);
0972     return 0;
0973 }
0974 
0975 static int vidioc_g_tuner(struct file *file, void *priv,
0976               struct v4l2_tuner *t)
0977 {
0978     struct cx8802_dev *dev = video_drvdata(file);
0979     struct cx88_core *core = dev->core;
0980     u32 reg;
0981 
0982     if (unlikely(core->board.tuner_type == UNSET))
0983         return -EINVAL;
0984     if (t->index != 0)
0985         return -EINVAL;
0986 
0987     strscpy(t->name, "Television", sizeof(t->name));
0988     t->capability = V4L2_TUNER_CAP_NORM;
0989     t->rangehigh  = 0xffffffffUL;
0990     call_all(core, tuner, g_tuner, t);
0991 
0992     cx88_get_stereo(core, t);
0993     reg = cx_read(MO_DEVICE_STATUS);
0994     t->signal = (reg & (1 << 5)) ? 0xffff : 0x0000;
0995     return 0;
0996 }
0997 
0998 static int vidioc_s_tuner(struct file *file, void *priv,
0999               const struct v4l2_tuner *t)
1000 {
1001     struct cx8802_dev *dev = video_drvdata(file);
1002     struct cx88_core *core = dev->core;
1003 
1004     if (core->board.tuner_type == UNSET)
1005         return -EINVAL;
1006     if (t->index != 0)
1007         return -EINVAL;
1008 
1009     cx88_set_stereo(core, t->audmode, 1);
1010     return 0;
1011 }
1012 
1013 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm)
1014 {
1015     struct cx8802_dev *dev = video_drvdata(file);
1016     struct cx88_core *core = dev->core;
1017 
1018     *tvnorm = core->tvnorm;
1019     return 0;
1020 }
1021 
1022 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
1023 {
1024     struct cx8802_dev *dev = video_drvdata(file);
1025     struct cx88_core *core = dev->core;
1026 
1027     return cx88_set_tvnorm(core, id);
1028 }
1029 
1030 static const struct v4l2_file_operations mpeg_fops = {
1031     .owner         = THIS_MODULE,
1032     .open          = v4l2_fh_open,
1033     .release       = vb2_fop_release,
1034     .read          = vb2_fop_read,
1035     .poll          = vb2_fop_poll,
1036     .mmap          = vb2_fop_mmap,
1037     .unlocked_ioctl = video_ioctl2,
1038 };
1039 
1040 static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
1041     .vidioc_querycap      = vidioc_querycap,
1042     .vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
1043     .vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
1044     .vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
1045     .vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
1046     .vidioc_reqbufs       = vb2_ioctl_reqbufs,
1047     .vidioc_querybuf      = vb2_ioctl_querybuf,
1048     .vidioc_qbuf          = vb2_ioctl_qbuf,
1049     .vidioc_dqbuf         = vb2_ioctl_dqbuf,
1050     .vidioc_streamon      = vb2_ioctl_streamon,
1051     .vidioc_streamoff     = vb2_ioctl_streamoff,
1052     .vidioc_s_frequency   = vidioc_s_frequency,
1053     .vidioc_log_status    = vidioc_log_status,
1054     .vidioc_enum_input    = vidioc_enum_input,
1055     .vidioc_g_frequency   = vidioc_g_frequency,
1056     .vidioc_g_input       = vidioc_g_input,
1057     .vidioc_s_input       = vidioc_s_input,
1058     .vidioc_g_tuner       = vidioc_g_tuner,
1059     .vidioc_s_tuner       = vidioc_s_tuner,
1060     .vidioc_g_std         = vidioc_g_std,
1061     .vidioc_s_std         = vidioc_s_std,
1062     .vidioc_subscribe_event      = v4l2_ctrl_subscribe_event,
1063     .vidioc_unsubscribe_event    = v4l2_event_unsubscribe,
1064 };
1065 
1066 static const struct video_device cx8802_mpeg_template = {
1067     .name                 = "cx8802",
1068     .fops                 = &mpeg_fops,
1069     .ioctl_ops        = &mpeg_ioctl_ops,
1070     .tvnorms              = CX88_NORMS,
1071 };
1072 
1073 /* ------------------------------------------------------------------ */
1074 
1075 /* The CX8802 MPEG API will call this when we can use the hardware */
1076 static int cx8802_blackbird_advise_acquire(struct cx8802_driver *drv)
1077 {
1078     struct cx88_core *core = drv->core;
1079     int err = 0;
1080 
1081     switch (core->boardnr) {
1082     case CX88_BOARD_HAUPPAUGE_HVR1300:
1083         /*
1084          * By default, core setup will leave the cx22702 out of reset,
1085          * on the bus.
1086          * We left the hardware on power up with the cx22702 active.
1087          * We're being given access to re-arrange the GPIOs.
1088          * Take the bus off the cx22702 and put the cx23416 on it.
1089          */
1090         /* Toggle reset on cx22702 leaving i2c active */
1091         cx_set(MO_GP0_IO, 0x00000080);
1092         udelay(1000);
1093         cx_clear(MO_GP0_IO, 0x00000080);
1094         udelay(50);
1095         cx_set(MO_GP0_IO, 0x00000080);
1096         udelay(1000);
1097         /* tri-state the cx22702 pins */
1098         cx_set(MO_GP0_IO, 0x00000004);
1099         udelay(1000);
1100         break;
1101     default:
1102         err = -ENODEV;
1103     }
1104     return err;
1105 }
1106 
1107 /* The CX8802 MPEG API will call this when we need to release the hardware */
1108 static int cx8802_blackbird_advise_release(struct cx8802_driver *drv)
1109 {
1110     struct cx88_core *core = drv->core;
1111     int err = 0;
1112 
1113     switch (core->boardnr) {
1114     case CX88_BOARD_HAUPPAUGE_HVR1300:
1115         /* Exit leaving the cx23416 on the bus */
1116         break;
1117     default:
1118         err = -ENODEV;
1119     }
1120     return err;
1121 }
1122 
1123 static void blackbird_unregister_video(struct cx8802_dev *dev)
1124 {
1125     video_unregister_device(&dev->mpeg_dev);
1126 }
1127 
1128 static int blackbird_register_video(struct cx8802_dev *dev)
1129 {
1130     int err;
1131 
1132     cx88_vdev_init(dev->core, dev->pci, &dev->mpeg_dev,
1133                &cx8802_mpeg_template, "mpeg");
1134     dev->mpeg_dev.ctrl_handler = &dev->cxhdl.hdl;
1135     video_set_drvdata(&dev->mpeg_dev, dev);
1136     dev->mpeg_dev.queue = &dev->vb2_mpegq;
1137     dev->mpeg_dev.device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
1138                     V4L2_CAP_VIDEO_CAPTURE;
1139     if (dev->core->board.tuner_type != UNSET)
1140         dev->mpeg_dev.device_caps |= V4L2_CAP_TUNER;
1141     err = video_register_device(&dev->mpeg_dev, VFL_TYPE_VIDEO, -1);
1142     if (err < 0) {
1143         pr_info("can't register mpeg device\n");
1144         return err;
1145     }
1146     pr_info("registered device %s [mpeg]\n",
1147         video_device_node_name(&dev->mpeg_dev));
1148     return 0;
1149 }
1150 
1151 /* ----------------------------------------------------------- */
1152 
1153 static int cx8802_blackbird_probe(struct cx8802_driver *drv)
1154 {
1155     struct cx88_core *core = drv->core;
1156     struct cx8802_dev *dev = core->dvbdev;
1157     struct vb2_queue *q;
1158     int err;
1159 
1160     dprintk(1, "%s\n", __func__);
1161     dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
1162         core->boardnr,
1163         core->name,
1164         core->pci_bus,
1165         core->pci_slot);
1166 
1167     err = -ENODEV;
1168     if (!(core->board.mpeg & CX88_MPEG_BLACKBIRD))
1169         goto fail_core;
1170 
1171     dev->cxhdl.port = CX2341X_PORT_STREAMING;
1172     dev->cxhdl.width = core->width;
1173     dev->cxhdl.height = core->height;
1174     dev->cxhdl.func = blackbird_mbox_func;
1175     dev->cxhdl.priv = dev;
1176     err = cx2341x_handler_init(&dev->cxhdl, 36);
1177     if (err)
1178         goto fail_core;
1179     v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl, NULL, false);
1180 
1181     /* blackbird stuff */
1182     pr_info("cx23416 based mpeg encoder (blackbird reference design)\n");
1183     host_setup(dev->core);
1184 
1185     blackbird_initialize_codec(dev);
1186 
1187     /* initial device configuration: needed ? */
1188 //  init_controls(core);
1189     cx88_set_tvnorm(core, core->tvnorm);
1190     cx88_video_mux(core, 0);
1191     cx2341x_handler_set_50hz(&dev->cxhdl, core->height == 576);
1192     cx2341x_handler_setup(&dev->cxhdl);
1193 
1194     q = &dev->vb2_mpegq;
1195     q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1196     q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
1197     q->gfp_flags = GFP_DMA32;
1198     q->min_buffers_needed = 2;
1199     q->drv_priv = dev;
1200     q->buf_struct_size = sizeof(struct cx88_buffer);
1201     q->ops = &blackbird_qops;
1202     q->mem_ops = &vb2_dma_sg_memops;
1203     q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1204     q->lock = &core->lock;
1205     q->dev = &dev->pci->dev;
1206 
1207     err = vb2_queue_init(q);
1208     if (err < 0)
1209         goto fail_core;
1210 
1211     blackbird_register_video(dev);
1212 
1213     return 0;
1214 
1215 fail_core:
1216     return err;
1217 }
1218 
1219 static int cx8802_blackbird_remove(struct cx8802_driver *drv)
1220 {
1221     struct cx88_core *core = drv->core;
1222     struct cx8802_dev *dev = core->dvbdev;
1223 
1224     /* blackbird */
1225     blackbird_unregister_video(drv->core->dvbdev);
1226     v4l2_ctrl_handler_free(&dev->cxhdl.hdl);
1227 
1228     return 0;
1229 }
1230 
1231 static struct cx8802_driver cx8802_blackbird_driver = {
1232     .type_id    = CX88_MPEG_BLACKBIRD,
1233     .hw_access  = CX8802_DRVCTL_SHARED,
1234     .probe      = cx8802_blackbird_probe,
1235     .remove     = cx8802_blackbird_remove,
1236     .advise_acquire = cx8802_blackbird_advise_acquire,
1237     .advise_release = cx8802_blackbird_advise_release,
1238 };
1239 
1240 static int __init blackbird_init(void)
1241 {
1242     pr_info("cx2388x blackbird driver version %s loaded\n",
1243         CX88_VERSION);
1244     return cx8802_register_driver(&cx8802_blackbird_driver);
1245 }
1246 
1247 static void __exit blackbird_fini(void)
1248 {
1249     cx8802_unregister_driver(&cx8802_blackbird_driver);
1250 }
1251 
1252 module_init(blackbird_init);
1253 module_exit(blackbird_fini);