0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
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
0049
0050 #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
0051
0052
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,
0072 BLACKBIRD_END_NOW,
0073 };
0074
0075 enum blackbird_framerate {
0076 BLACKBIRD_FRAMERATE_NTSC_30,
0077 BLACKBIRD_FRAMERATE_PAL_25
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,
0147 BLACKBIRD_FIELD1_SAA7115 = 0x00F0,
0148 BLACKBIRD_FIELD1_MICRONAS = 0x0105,
0149 };
0150
0151 enum blackbird_field2_lines {
0152 BLACKBIRD_FIELD2_SAA7114 = 0x00EF,
0153 BLACKBIRD_FIELD2_SAA7115 = 0x00F0,
0154 BLACKBIRD_FIELD2_MICRONAS = 0x0106,
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
0180 #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 )
0181 #define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC )
0182 #define IVTV_REG_SPU (0x9050 )
0183 #define IVTV_REG_HW_BLOCKS (0x9054 )
0184 #define IVTV_REG_VPU (0x9058 )
0185 #define IVTV_REG_APU (0xA064 )
0186
0187
0188
0189 static void host_setup(struct cx88_core *core)
0190 {
0191
0192 cx_write(MO_GPHST_SOFT_RST, 1);
0193 udelay(100);
0194 cx_write(MO_GPHST_SOFT_RST, 0);
0195 udelay(100);
0196
0197
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
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
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
0330
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;
0346 memory_write(dev->core, dev->mailbox, flag);
0347
0348
0349 memory_write(dev->core, dev->mailbox + 1, command);
0350
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;
0360 memory_write(dev->core, dev->mailbox, flag);
0361
0362
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
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
0393
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
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
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
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535 static void blackbird_codec_settings(struct cx8802_dev *dev)
0536 {
0537 struct cx88_core *core = dev->core;
0538
0539
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);
0558 if (retval < 0) {
0559
0560 cx_write(MO_SRST_IO, 0);
0561 cx_write(MO_SRST_IO, 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
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);
0590 cx_clear(MO_INPUT_FORMAT, 0x100);
0591 cx_write(MO_VBOS_CONTROL, 0x84A00);
0592 cx_clear(MO_OUTPUT_FORMAT, 0x0008);
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
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
0628 cx_clear(AUD_VOL_CTL, (1 << 6));
0629
0630 blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0, 0);
0631
0632
0633 blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
0634
0635 cx2341x_handler_set_busy(&dev->cxhdl, 1);
0636
0637
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
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
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
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
1085
1086
1087
1088
1089
1090
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
1098 cx_set(MO_GP0_IO, 0x00000004);
1099 udelay(1000);
1100 break;
1101 default:
1102 err = -ENODEV;
1103 }
1104 return err;
1105 }
1106
1107
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
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
1182 pr_info("cx23416 based mpeg encoder (blackbird reference design)\n");
1183 host_setup(dev->core);
1184
1185 blackbird_initialize_codec(dev);
1186
1187
1188
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
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);