1 /* 2 * 3 * Support for a cx23416 mpeg encoder via cx2388x host port. 4 * "blackbird" reference design. 5 * 6 * (c) 2004 Jelle Foks <jelle@foks.us> 7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> 8 * 9 * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org> 10 * - video_ioctl2 conversion 11 * 12 * Includes parts from the ivtv driver <http://sourceforge.net/projects/ivtv/> 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License as published by 16 * the Free Software Foundation; either version 2 of the License, or 17 * (at your option) any later version. 18 * 19 * This program is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * GNU General Public License for more details. 23 * 24 * You should have received a copy of the GNU General Public License 25 * along with this program; if not, write to the Free Software 26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 */ 28 29 #include <linux/module.h> 30 #include <linux/init.h> 31 #include <linux/slab.h> 32 #include <linux/fs.h> 33 #include <linux/delay.h> 34 #include <linux/device.h> 35 #include <linux/firmware.h> 36 #include <media/v4l2-common.h> 37 #include <media/v4l2-ioctl.h> 38 #include <media/v4l2-event.h> 39 #include <media/cx2341x.h> 40 41 #include "cx88.h" 42 43 MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards"); 44 MODULE_AUTHOR("Jelle Foks <jelle@foks.us>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 45 MODULE_LICENSE("GPL"); 46 MODULE_VERSION(CX88_VERSION); 47 48 static unsigned int debug; 49 module_param(debug,int,0644); 50 MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); 51 52 #define dprintk(level, fmt, arg...) do { \ 53 if (debug + 1 > level) \ 54 printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg); \ 55 } while(0) 56 57 /* ------------------------------------------------------------------ */ 58 59 #define BLACKBIRD_FIRM_IMAGE_SIZE 376836 60 61 /* defines below are from ivtv-driver.h */ 62 63 #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF 64 65 /* Firmware API commands */ 66 #define IVTV_API_STD_TIMEOUT 500 67 68 enum blackbird_capture_type { 69 BLACKBIRD_MPEG_CAPTURE, 70 BLACKBIRD_RAW_CAPTURE, 71 BLACKBIRD_RAW_PASSTHRU_CAPTURE 72 }; 73 enum blackbird_capture_bits { 74 BLACKBIRD_RAW_BITS_NONE = 0x00, 75 BLACKBIRD_RAW_BITS_YUV_CAPTURE = 0x01, 76 BLACKBIRD_RAW_BITS_PCM_CAPTURE = 0x02, 77 BLACKBIRD_RAW_BITS_VBI_CAPTURE = 0x04, 78 BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08, 79 BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE = 0x10 80 }; 81 enum blackbird_capture_end { 82 BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */ 83 BLACKBIRD_END_NOW, /* stop immediately, no irq */ 84 }; 85 enum blackbird_framerate { 86 BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */ 87 BLACKBIRD_FRAMERATE_PAL_25 /* PAL: 25fps */ 88 }; 89 enum blackbird_stream_port { 90 BLACKBIRD_OUTPUT_PORT_MEMORY, 91 BLACKBIRD_OUTPUT_PORT_STREAMING, 92 BLACKBIRD_OUTPUT_PORT_SERIAL 93 }; 94 enum blackbird_data_xfer_status { 95 BLACKBIRD_MORE_BUFFERS_FOLLOW, 96 BLACKBIRD_LAST_BUFFER, 97 }; 98 enum blackbird_picture_mask { 99 BLACKBIRD_PICTURE_MASK_NONE, 100 BLACKBIRD_PICTURE_MASK_I_FRAMES, 101 BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3, 102 BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7, 103 }; 104 enum blackbird_vbi_mode_bits { 105 BLACKBIRD_VBI_BITS_SLICED, 106 BLACKBIRD_VBI_BITS_RAW, 107 }; 108 enum blackbird_vbi_insertion_bits { 109 BLACKBIRD_VBI_BITS_INSERT_IN_XTENSION_USR_DATA, 110 BLACKBIRD_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1, 111 BLACKBIRD_VBI_BITS_SEPARATE_STREAM = 0x2 << 1, 112 BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, 113 BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, 114 }; 115 enum blackbird_dma_unit { 116 BLACKBIRD_DMA_BYTES, 117 BLACKBIRD_DMA_FRAMES, 118 }; 119 enum blackbird_dma_transfer_status_bits { 120 BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01, 121 BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04, 122 BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10, 123 }; 124 enum blackbird_pause { 125 BLACKBIRD_PAUSE_ENCODING, 126 BLACKBIRD_RESUME_ENCODING, 127 }; 128 enum blackbird_copyright { 129 BLACKBIRD_COPYRIGHT_OFF, 130 BLACKBIRD_COPYRIGHT_ON, 131 }; 132 enum blackbird_notification_type { 133 BLACKBIRD_NOTIFICATION_REFRESH, 134 }; 135 enum blackbird_notification_status { 136 BLACKBIRD_NOTIFICATION_OFF, 137 BLACKBIRD_NOTIFICATION_ON, 138 }; 139 enum blackbird_notification_mailbox { 140 BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1, 141 }; 142 enum blackbird_field1_lines { 143 BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */ 144 BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */ 145 BLACKBIRD_FIELD1_MICRONAS = 0x0105, /* 261 */ 146 }; 147 enum blackbird_field2_lines { 148 BLACKBIRD_FIELD2_SAA7114 = 0x00EF, /* 239 */ 149 BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */ 150 BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */ 151 }; 152 enum blackbird_custom_data_type { 153 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, 154 BLACKBIRD_CUSTOM_PRIVATE_PACKET, 155 }; 156 enum blackbird_mute { 157 BLACKBIRD_UNMUTE, 158 BLACKBIRD_MUTE, 159 }; 160 enum blackbird_mute_video_mask { 161 BLACKBIRD_MUTE_VIDEO_V_MASK = 0x0000FF00, 162 BLACKBIRD_MUTE_VIDEO_U_MASK = 0x00FF0000, 163 BLACKBIRD_MUTE_VIDEO_Y_MASK = 0xFF000000, 164 }; 165 enum blackbird_mute_video_shift { 166 BLACKBIRD_MUTE_VIDEO_V_SHIFT = 8, 167 BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16, 168 BLACKBIRD_MUTE_VIDEO_Y_SHIFT = 24, 169 }; 170 171 /* Registers */ 172 #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/) 173 #define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC /*| IVTV_REG_OFFSET*/) 174 #define IVTV_REG_SPU (0x9050 /*| IVTV_REG_OFFSET*/) 175 #define IVTV_REG_HW_BLOCKS (0x9054 /*| IVTV_REG_OFFSET*/) 176 #define IVTV_REG_VPU (0x9058 /*| IVTV_REG_OFFSET*/) 177 #define IVTV_REG_APU (0xA064 /*| IVTV_REG_OFFSET*/) 178 179 /* ------------------------------------------------------------------ */ 180 181 static void host_setup(struct cx88_core *core) 182 { 183 /* toggle reset of the host */ 184 cx_write(MO_GPHST_SOFT_RST, 1); 185 udelay(100); 186 cx_write(MO_GPHST_SOFT_RST, 0); 187 udelay(100); 188 189 /* host port setup */ 190 cx_write(MO_GPHST_WSC, 0x44444444U); 191 cx_write(MO_GPHST_XFR, 0); 192 cx_write(MO_GPHST_WDTH, 15); 193 cx_write(MO_GPHST_HDSHK, 0); 194 cx_write(MO_GPHST_MUX16, 0x44448888U); 195 cx_write(MO_GPHST_MODE, 0); 196 } 197 198 /* ------------------------------------------------------------------ */ 199 200 #define P1_MDATA0 0x390000 201 #define P1_MDATA1 0x390001 202 #define P1_MDATA2 0x390002 203 #define P1_MDATA3 0x390003 204 #define P1_MADDR2 0x390004 205 #define P1_MADDR1 0x390005 206 #define P1_MADDR0 0x390006 207 #define P1_RDATA0 0x390008 208 #define P1_RDATA1 0x390009 209 #define P1_RDATA2 0x39000A 210 #define P1_RDATA3 0x39000B 211 #define P1_RADDR0 0x39000C 212 #define P1_RADDR1 0x39000D 213 #define P1_RRDWR 0x39000E 214 215 static int wait_ready_gpio0_bit1(struct cx88_core *core, u32 state) 216 { 217 unsigned long timeout = jiffies + msecs_to_jiffies(1); 218 u32 gpio0,need; 219 220 need = state ? 2 : 0; 221 for (;;) { 222 gpio0 = cx_read(MO_GP0_IO) & 2; 223 if (need == gpio0) 224 return 0; 225 if (time_after(jiffies,timeout)) 226 return -1; 227 udelay(1); 228 } 229 } 230 231 static int memory_write(struct cx88_core *core, u32 address, u32 value) 232 { 233 /* Warning: address is dword address (4 bytes) */ 234 cx_writeb(P1_MDATA0, (unsigned int)value); 235 cx_writeb(P1_MDATA1, (unsigned int)(value >> 8)); 236 cx_writeb(P1_MDATA2, (unsigned int)(value >> 16)); 237 cx_writeb(P1_MDATA3, (unsigned int)(value >> 24)); 238 cx_writeb(P1_MADDR2, (unsigned int)(address >> 16) | 0x40); 239 cx_writeb(P1_MADDR1, (unsigned int)(address >> 8)); 240 cx_writeb(P1_MADDR0, (unsigned int)address); 241 cx_read(P1_MDATA0); 242 cx_read(P1_MADDR0); 243 244 return wait_ready_gpio0_bit1(core,1); 245 } 246 247 static int memory_read(struct cx88_core *core, u32 address, u32 *value) 248 { 249 int retval; 250 u32 val; 251 252 /* Warning: address is dword address (4 bytes) */ 253 cx_writeb(P1_MADDR2, (unsigned int)(address >> 16) & ~0xC0); 254 cx_writeb(P1_MADDR1, (unsigned int)(address >> 8)); 255 cx_writeb(P1_MADDR0, (unsigned int)address); 256 cx_read(P1_MADDR0); 257 258 retval = wait_ready_gpio0_bit1(core,1); 259 260 cx_writeb(P1_MDATA3, 0); 261 val = (unsigned char)cx_read(P1_MDATA3) << 24; 262 cx_writeb(P1_MDATA2, 0); 263 val |= (unsigned char)cx_read(P1_MDATA2) << 16; 264 cx_writeb(P1_MDATA1, 0); 265 val |= (unsigned char)cx_read(P1_MDATA1) << 8; 266 cx_writeb(P1_MDATA0, 0); 267 val |= (unsigned char)cx_read(P1_MDATA0); 268 269 *value = val; 270 return retval; 271 } 272 273 static int register_write(struct cx88_core *core, u32 address, u32 value) 274 { 275 cx_writeb(P1_RDATA0, (unsigned int)value); 276 cx_writeb(P1_RDATA1, (unsigned int)(value >> 8)); 277 cx_writeb(P1_RDATA2, (unsigned int)(value >> 16)); 278 cx_writeb(P1_RDATA3, (unsigned int)(value >> 24)); 279 cx_writeb(P1_RADDR0, (unsigned int)address); 280 cx_writeb(P1_RADDR1, (unsigned int)(address >> 8)); 281 cx_writeb(P1_RRDWR, 1); 282 cx_read(P1_RDATA0); 283 cx_read(P1_RADDR0); 284 285 return wait_ready_gpio0_bit1(core,1); 286 } 287 288 289 static int register_read(struct cx88_core *core, u32 address, u32 *value) 290 { 291 int retval; 292 u32 val; 293 294 cx_writeb(P1_RADDR0, (unsigned int)address); 295 cx_writeb(P1_RADDR1, (unsigned int)(address >> 8)); 296 cx_writeb(P1_RRDWR, 0); 297 cx_read(P1_RADDR0); 298 299 retval = wait_ready_gpio0_bit1(core,1); 300 val = (unsigned char)cx_read(P1_RDATA0); 301 val |= (unsigned char)cx_read(P1_RDATA1) << 8; 302 val |= (unsigned char)cx_read(P1_RDATA2) << 16; 303 val |= (unsigned char)cx_read(P1_RDATA3) << 24; 304 305 *value = val; 306 return retval; 307 } 308 309 /* ------------------------------------------------------------------ */ 310 311 static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]) 312 { 313 struct cx8802_dev *dev = priv; 314 unsigned long timeout; 315 u32 value, flag, retval; 316 int i; 317 318 dprintk(1,"%s: 0x%X\n", __func__, command); 319 320 /* this may not be 100% safe if we can't read any memory location 321 without side effects */ 322 memory_read(dev->core, dev->mailbox - 4, &value); 323 if (value != 0x12345678) { 324 dprintk(0, "Firmware and/or mailbox pointer not initialized or corrupted\n"); 325 return -EIO; 326 } 327 328 memory_read(dev->core, dev->mailbox, &flag); 329 if (flag) { 330 dprintk(0, "ERROR: Mailbox appears to be in use (%x)\n", flag); 331 return -EIO; 332 } 333 334 flag |= 1; /* tell 'em we're working on it */ 335 memory_write(dev->core, dev->mailbox, flag); 336 337 /* write command + args + fill remaining with zeros */ 338 memory_write(dev->core, dev->mailbox + 1, command); /* command code */ 339 memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */ 340 for (i = 0; i < in; i++) { 341 memory_write(dev->core, dev->mailbox + 4 + i, data[i]); 342 dprintk(1, "API Input %d = %d\n", i, data[i]); 343 } 344 for (; i < CX2341X_MBOX_MAX_DATA; i++) 345 memory_write(dev->core, dev->mailbox + 4 + i, 0); 346 347 flag |= 3; /* tell 'em we're done writing */ 348 memory_write(dev->core, dev->mailbox, flag); 349 350 /* wait for firmware to handle the API command */ 351 timeout = jiffies + msecs_to_jiffies(1000); 352 for (;;) { 353 memory_read(dev->core, dev->mailbox, &flag); 354 if (0 != (flag & 4)) 355 break; 356 if (time_after(jiffies,timeout)) { 357 dprintk(0, "ERROR: API Mailbox timeout %x\n", command); 358 return -EIO; 359 } 360 udelay(10); 361 } 362 363 /* read output values */ 364 for (i = 0; i < out; i++) { 365 memory_read(dev->core, dev->mailbox + 4 + i, data + i); 366 dprintk(1, "API Output %d = %d\n", i, data[i]); 367 } 368 369 memory_read(dev->core, dev->mailbox + 2, &retval); 370 dprintk(1, "API result = %d\n",retval); 371 372 flag = 0; 373 memory_write(dev->core, dev->mailbox, flag); 374 return retval; 375 } 376 /* ------------------------------------------------------------------ */ 377 378 /* We don't need to call the API often, so using just one mailbox will probably suffice */ 379 static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command, 380 u32 inputcnt, u32 outputcnt, ...) 381 { 382 u32 data[CX2341X_MBOX_MAX_DATA]; 383 va_list vargs; 384 int i, err; 385 386 va_start(vargs, outputcnt); 387 388 for (i = 0; i < inputcnt; i++) { 389 data[i] = va_arg(vargs, int); 390 } 391 err = blackbird_mbox_func(dev, command, inputcnt, outputcnt, data); 392 for (i = 0; i < outputcnt; i++) { 393 int *vptr = va_arg(vargs, int *); 394 *vptr = data[i]; 395 } 396 va_end(vargs); 397 return err; 398 } 399 400 static int blackbird_find_mailbox(struct cx8802_dev *dev) 401 { 402 u32 signature[4]={0x12345678, 0x34567812, 0x56781234, 0x78123456}; 403 int signaturecnt=0; 404 u32 value; 405 int i; 406 407 for (i = 0; i < BLACKBIRD_FIRM_IMAGE_SIZE; i++) { 408 memory_read(dev->core, i, &value); 409 if (value == signature[signaturecnt]) 410 signaturecnt++; 411 else 412 signaturecnt = 0; 413 if (4 == signaturecnt) { 414 dprintk(1, "Mailbox signature found\n"); 415 return i+1; 416 } 417 } 418 dprintk(0, "Mailbox signature values not found!\n"); 419 return -EIO; 420 } 421 422 static int blackbird_load_firmware(struct cx8802_dev *dev) 423 { 424 static const unsigned char magic[8] = { 425 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa 426 }; 427 const struct firmware *firmware; 428 int i, retval = 0; 429 u32 value = 0; 430 u32 checksum = 0; 431 __le32 *dataptr; 432 433 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED); 434 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); 435 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640); 436 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A); 437 msleep(1); 438 retval |= register_write(dev->core, IVTV_REG_APU, 0); 439 440 if (retval < 0) 441 dprintk(0, "Error with register_write\n"); 442 443 retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME, 444 &dev->pci->dev); 445 446 447 if (retval != 0) { 448 pr_err("Hotplug firmware request failed (%s).\n", 449 CX2341X_FIRM_ENC_FILENAME); 450 pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n"); 451 return -EIO; 452 } 453 454 if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) { 455 pr_err("Firmware size mismatch (have %zd, expected %d)\n", 456 firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE); 457 release_firmware(firmware); 458 return -EINVAL; 459 } 460 461 if (0 != memcmp(firmware->data, magic, 8)) { 462 pr_err("Firmware magic mismatch, wrong file?\n"); 463 release_firmware(firmware); 464 return -EINVAL; 465 } 466 467 /* transfer to the chip */ 468 dprintk(1,"Loading firmware ...\n"); 469 dataptr = (__le32 *)firmware->data; 470 for (i = 0; i < (firmware->size >> 2); i++) { 471 value = le32_to_cpu(*dataptr); 472 checksum += ~value; 473 memory_write(dev->core, i, value); 474 dataptr++; 475 } 476 477 /* read back to verify with the checksum */ 478 for (i--; i >= 0; i--) { 479 memory_read(dev->core, i, &value); 480 checksum -= ~value; 481 } 482 release_firmware(firmware); 483 if (checksum) { 484 pr_err("Firmware load might have failed (checksum mismatch).\n"); 485 return -EIO; 486 } 487 dprintk(0, "Firmware upload successful.\n"); 488 489 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); 490 retval |= register_read(dev->core, IVTV_REG_SPU, &value); 491 retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE); 492 msleep(1); 493 494 retval |= register_read(dev->core, IVTV_REG_VPU, &value); 495 retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8); 496 497 if (retval < 0) 498 dprintk(0, "Error with register_write\n"); 499 return 0; 500 } 501 502 /** 503 Settings used by the windows tv app for PVR2000: 504 ================================================================================================================= 505 Profile | Codec | Resolution | CBR/VBR | Video Qlty | V. Bitrate | Frmrate | Audio Codec | A. Bitrate | A. Mode 506 ----------------------------------------------------------------------------------------------------------------- 507 MPEG-1 | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 2000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo 508 MPEG-2 | MPEG2 | 720x576PAL | VBR | 600 :Good | 4000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo 509 VCD | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 1150 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo 510 DVD | MPEG2 | 720x576PAL | VBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo 511 DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo 512 ================================================================================================================= 513 *DB: "DirectBurn" 514 */ 515 516 static void blackbird_codec_settings(struct cx8802_dev *dev) 517 { 518 struct cx88_core *core = dev->core; 519 520 /* assign frame size */ 521 blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, 522 core->height, core->width); 523 524 dev->cxhdl.width = core->width; 525 dev->cxhdl.height = core->height; 526 cx2341x_handler_set_50hz(&dev->cxhdl, dev->core->tvnorm & V4L2_STD_625_50); 527 cx2341x_handler_setup(&dev->cxhdl); 528 } 529 530 static int blackbird_initialize_codec(struct cx8802_dev *dev) 531 { 532 struct cx88_core *core = dev->core; 533 int version; 534 int retval; 535 536 dprintk(1,"Initialize codec\n"); 537 retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ 538 if (retval < 0) { 539 /* ping was not successful, reset and upload firmware */ 540 cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */ 541 cx_write(MO_SRST_IO, 1); /* SYS_RSTO=1 */ 542 retval = blackbird_load_firmware(dev); 543 if (retval < 0) 544 return retval; 545 546 retval = blackbird_find_mailbox(dev); 547 if (retval < 0) 548 return -1; 549 550 dev->mailbox = retval; 551 552 retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ 553 if (retval < 0) { 554 dprintk(0, "ERROR: Firmware ping failed!\n"); 555 return -1; 556 } 557 558 retval = blackbird_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version); 559 if (retval < 0) { 560 dprintk(0, "ERROR: Firmware get encoder version failed!\n"); 561 return -1; 562 } 563 dprintk(0, "Firmware version is 0x%08x\n", version); 564 } 565 566 cx_write(MO_PINMUX_IO, 0x88); /* 656-8bit IO and enable MPEG parallel IO */ 567 cx_clear(MO_INPUT_FORMAT, 0x100); /* chroma subcarrier lock to normal? */ 568 cx_write(MO_VBOS_CONTROL, 0x84A00); /* no 656 mode, 8-bit pixels, disable VBI */ 569 cx_clear(MO_OUTPUT_FORMAT, 0x0008); /* Normal Y-limits to let the mpeg encoder sync */ 570 571 blackbird_codec_settings(dev); 572 573 blackbird_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0, 574 BLACKBIRD_FIELD1_SAA7115, 575 BLACKBIRD_FIELD2_SAA7115 576 ); 577 578 blackbird_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0, 579 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, 580 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 581 582 return 0; 583 } 584 585 static int blackbird_start_codec(struct cx8802_dev *dev) 586 { 587 struct cx88_core *core = dev->core; 588 /* start capturing to the host interface */ 589 u32 reg; 590 591 int i; 592 int lastchange = -1; 593 int lastval = 0; 594 595 for (i = 0; (i < 10) && (i < (lastchange + 4)); i++) { 596 reg = cx_read(AUD_STATUS); 597 598 dprintk(1, "AUD_STATUS:%dL: 0x%x\n", i, reg); 599 if ((reg & 0x0F) != lastval) { 600 lastval = reg & 0x0F; 601 lastchange = i; 602 } 603 msleep(100); 604 } 605 606 /* unmute audio source */ 607 cx_clear(AUD_VOL_CTL, (1 << 6)); 608 609 blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0, 0); 610 611 /* initialize the video input */ 612 blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0); 613 614 cx2341x_handler_set_busy(&dev->cxhdl, 1); 615 616 /* start capturing to the host interface */ 617 blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, 618 BLACKBIRD_MPEG_CAPTURE, 619 BLACKBIRD_RAW_BITS_NONE 620 ); 621 622 return 0; 623 } 624 625 static int blackbird_stop_codec(struct cx8802_dev *dev) 626 { 627 blackbird_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, 628 BLACKBIRD_END_NOW, 629 BLACKBIRD_MPEG_CAPTURE, 630 BLACKBIRD_RAW_BITS_NONE 631 ); 632 633 cx2341x_handler_set_busy(&dev->cxhdl, 0); 634 635 return 0; 636 } 637 638 /* ------------------------------------------------------------------ */ 639 640 static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, 641 unsigned int *num_buffers, unsigned int *num_planes, 642 unsigned int sizes[], void *alloc_ctxs[]) 643 { 644 struct cx8802_dev *dev = q->drv_priv; 645 646 *num_planes = 1; 647 dev->ts_packet_size = 188 * 4; 648 dev->ts_packet_count = 32; 649 sizes[0] = dev->ts_packet_size * dev->ts_packet_count; 650 alloc_ctxs[0] = dev->alloc_ctx; 651 return 0; 652 } 653 654 static int buffer_prepare(struct vb2_buffer *vb) 655 { 656 struct cx8802_dev *dev = vb->vb2_queue->drv_priv; 657 struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); 658 659 return cx8802_buf_prepare(vb->vb2_queue, dev, buf); 660 } 661 662 static void buffer_finish(struct vb2_buffer *vb) 663 { 664 struct cx8802_dev *dev = vb->vb2_queue->drv_priv; 665 struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); 666 struct cx88_riscmem *risc = &buf->risc; 667 668 if (risc->cpu) 669 pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); 670 memset(risc, 0, sizeof(*risc)); 671 } 672 673 static void buffer_queue(struct vb2_buffer *vb) 674 { 675 struct cx8802_dev *dev = vb->vb2_queue->drv_priv; 676 struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); 677 678 cx8802_buf_queue(dev, buf); 679 } 680 681 static int start_streaming(struct vb2_queue *q, unsigned int count) 682 { 683 struct cx8802_dev *dev = q->drv_priv; 684 struct cx88_dmaqueue *dmaq = &dev->mpegq; 685 struct cx8802_driver *drv; 686 struct cx88_buffer *buf; 687 unsigned long flags; 688 int err; 689 690 /* Make sure we can acquire the hardware */ 691 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); 692 if (!drv) { 693 dprintk(1, "%s: blackbird driver is not loaded\n", __func__); 694 err = -ENODEV; 695 goto fail; 696 } 697 698 err = drv->request_acquire(drv); 699 if (err != 0) { 700 dprintk(1, "%s: Unable to acquire hardware, %d\n", __func__, err); 701 goto fail; 702 } 703 704 if (blackbird_initialize_codec(dev) < 0) { 705 drv->request_release(drv); 706 err = -EINVAL; 707 goto fail; 708 } 709 710 err = blackbird_start_codec(dev); 711 if (err == 0) { 712 buf = list_entry(dmaq->active.next, struct cx88_buffer, list); 713 cx8802_start_dma(dev, dmaq, buf); 714 return 0; 715 } 716 717 fail: 718 spin_lock_irqsave(&dev->slock, flags); 719 while (!list_empty(&dmaq->active)) { 720 struct cx88_buffer *buf = list_entry(dmaq->active.next, 721 struct cx88_buffer, list); 722 723 list_del(&buf->list); 724 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED); 725 } 726 spin_unlock_irqrestore(&dev->slock, flags); 727 return err; 728 } 729 730 static void stop_streaming(struct vb2_queue *q) 731 { 732 struct cx8802_dev *dev = q->drv_priv; 733 struct cx88_dmaqueue *dmaq = &dev->mpegq; 734 struct cx8802_driver *drv = NULL; 735 unsigned long flags; 736 737 cx8802_cancel_buffers(dev); 738 blackbird_stop_codec(dev); 739 740 /* Make sure we release the hardware */ 741 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); 742 WARN_ON(!drv); 743 if (drv) 744 drv->request_release(drv); 745 746 spin_lock_irqsave(&dev->slock, flags); 747 while (!list_empty(&dmaq->active)) { 748 struct cx88_buffer *buf = list_entry(dmaq->active.next, 749 struct cx88_buffer, list); 750 751 list_del(&buf->list); 752 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); 753 } 754 spin_unlock_irqrestore(&dev->slock, flags); 755 } 756 757 static struct vb2_ops blackbird_qops = { 758 .queue_setup = queue_setup, 759 .buf_prepare = buffer_prepare, 760 .buf_finish = buffer_finish, 761 .buf_queue = buffer_queue, 762 .wait_prepare = vb2_ops_wait_prepare, 763 .wait_finish = vb2_ops_wait_finish, 764 .start_streaming = start_streaming, 765 .stop_streaming = stop_streaming, 766 }; 767 768 /* ------------------------------------------------------------------ */ 769 770 static int vidioc_querycap(struct file *file, void *priv, 771 struct v4l2_capability *cap) 772 { 773 struct cx8802_dev *dev = video_drvdata(file); 774 struct cx88_core *core = dev->core; 775 776 strcpy(cap->driver, "cx88_blackbird"); 777 sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); 778 cx88_querycap(file, core, cap); 779 return 0; 780 } 781 782 static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, 783 struct v4l2_fmtdesc *f) 784 { 785 if (f->index != 0) 786 return -EINVAL; 787 788 strlcpy(f->description, "MPEG", sizeof(f->description)); 789 f->pixelformat = V4L2_PIX_FMT_MPEG; 790 f->flags = V4L2_FMT_FLAG_COMPRESSED; 791 return 0; 792 } 793 794 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 795 struct v4l2_format *f) 796 { 797 struct cx8802_dev *dev = video_drvdata(file); 798 struct cx88_core *core = dev->core; 799 800 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 801 f->fmt.pix.bytesperline = 0; 802 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; 803 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 804 f->fmt.pix.width = core->width; 805 f->fmt.pix.height = core->height; 806 f->fmt.pix.field = core->field; 807 return 0; 808 } 809 810 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 811 struct v4l2_format *f) 812 { 813 struct cx8802_dev *dev = video_drvdata(file); 814 struct cx88_core *core = dev->core; 815 unsigned maxw, maxh; 816 enum v4l2_field field; 817 818 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 819 f->fmt.pix.bytesperline = 0; 820 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; 821 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 822 823 maxw = norm_maxw(core->tvnorm); 824 maxh = norm_maxh(core->tvnorm); 825 826 field = f->fmt.pix.field; 827 828 switch (field) { 829 case V4L2_FIELD_TOP: 830 case V4L2_FIELD_BOTTOM: 831 case V4L2_FIELD_INTERLACED: 832 case V4L2_FIELD_SEQ_BT: 833 case V4L2_FIELD_SEQ_TB: 834 break; 835 default: 836 field = (f->fmt.pix.height > maxh / 2) 837 ? V4L2_FIELD_INTERLACED 838 : V4L2_FIELD_BOTTOM; 839 break; 840 } 841 if (V4L2_FIELD_HAS_T_OR_B(field)) 842 maxh /= 2; 843 844 v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, 845 &f->fmt.pix.height, 32, maxh, 0, 0); 846 f->fmt.pix.field = field; 847 return 0; 848 } 849 850 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 851 struct v4l2_format *f) 852 { 853 struct cx8802_dev *dev = video_drvdata(file); 854 struct cx88_core *core = dev->core; 855 856 if (vb2_is_busy(&dev->vb2_mpegq)) 857 return -EBUSY; 858 if (core->v4ldev && (vb2_is_busy(&core->v4ldev->vb2_vidq) || 859 vb2_is_busy(&core->v4ldev->vb2_vbiq))) 860 return -EBUSY; 861 vidioc_try_fmt_vid_cap(file, priv, f); 862 core->width = f->fmt.pix.width; 863 core->height = f->fmt.pix.height; 864 core->field = f->fmt.pix.field; 865 cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); 866 blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, 867 f->fmt.pix.height, f->fmt.pix.width); 868 return 0; 869 } 870 871 static int vidioc_s_frequency (struct file *file, void *priv, 872 const struct v4l2_frequency *f) 873 { 874 struct cx8802_dev *dev = video_drvdata(file); 875 struct cx88_core *core = dev->core; 876 bool streaming; 877 878 if (unlikely(UNSET == core->board.tuner_type)) 879 return -EINVAL; 880 if (unlikely(f->tuner != 0)) 881 return -EINVAL; 882 streaming = vb2_start_streaming_called(&dev->vb2_mpegq); 883 if (streaming) 884 blackbird_stop_codec(dev); 885 886 cx88_set_freq (core,f); 887 blackbird_initialize_codec(dev); 888 cx88_set_scale(core, core->width, core->height, 889 core->field); 890 if (streaming) 891 blackbird_start_codec(dev); 892 return 0; 893 } 894 895 static int vidioc_log_status (struct file *file, void *priv) 896 { 897 struct cx8802_dev *dev = video_drvdata(file); 898 struct cx88_core *core = dev->core; 899 char name[32 + 2]; 900 901 snprintf(name, sizeof(name), "%s/2", core->name); 902 call_all(core, core, log_status); 903 v4l2_ctrl_handler_log_status(&dev->cxhdl.hdl, name); 904 return 0; 905 } 906 907 static int vidioc_enum_input (struct file *file, void *priv, 908 struct v4l2_input *i) 909 { 910 struct cx8802_dev *dev = video_drvdata(file); 911 struct cx88_core *core = dev->core; 912 return cx88_enum_input (core,i); 913 } 914 915 static int vidioc_g_frequency (struct file *file, void *priv, 916 struct v4l2_frequency *f) 917 { 918 struct cx8802_dev *dev = video_drvdata(file); 919 struct cx88_core *core = dev->core; 920 921 if (unlikely(UNSET == core->board.tuner_type)) 922 return -EINVAL; 923 if (unlikely(f->tuner != 0)) 924 return -EINVAL; 925 926 f->frequency = core->freq; 927 call_all(core, tuner, g_frequency, f); 928 929 return 0; 930 } 931 932 static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) 933 { 934 struct cx8802_dev *dev = video_drvdata(file); 935 struct cx88_core *core = dev->core; 936 937 *i = core->input; 938 return 0; 939 } 940 941 static int vidioc_s_input (struct file *file, void *priv, unsigned int i) 942 { 943 struct cx8802_dev *dev = video_drvdata(file); 944 struct cx88_core *core = dev->core; 945 946 if (i >= 4) 947 return -EINVAL; 948 if (0 == INPUT(i).type) 949 return -EINVAL; 950 951 cx88_newstation(core); 952 cx88_video_mux(core,i); 953 return 0; 954 } 955 956 static int vidioc_g_tuner (struct file *file, void *priv, 957 struct v4l2_tuner *t) 958 { 959 struct cx8802_dev *dev = video_drvdata(file); 960 struct cx88_core *core = dev->core; 961 u32 reg; 962 963 if (unlikely(UNSET == core->board.tuner_type)) 964 return -EINVAL; 965 if (0 != t->index) 966 return -EINVAL; 967 968 strcpy(t->name, "Television"); 969 t->capability = V4L2_TUNER_CAP_NORM; 970 t->rangehigh = 0xffffffffUL; 971 call_all(core, tuner, g_tuner, t); 972 973 cx88_get_stereo(core ,t); 974 reg = cx_read(MO_DEVICE_STATUS); 975 t->signal = (reg & (1<<5)) ? 0xffff : 0x0000; 976 return 0; 977 } 978 979 static int vidioc_s_tuner (struct file *file, void *priv, 980 const struct v4l2_tuner *t) 981 { 982 struct cx8802_dev *dev = video_drvdata(file); 983 struct cx88_core *core = dev->core; 984 985 if (UNSET == core->board.tuner_type) 986 return -EINVAL; 987 if (0 != t->index) 988 return -EINVAL; 989 990 cx88_set_stereo(core, t->audmode, 1); 991 return 0; 992 } 993 994 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm) 995 { 996 struct cx8802_dev *dev = video_drvdata(file); 997 struct cx88_core *core = dev->core; 998 999 *tvnorm = core->tvnorm; 1000 return 0; 1001 } 1002 1003 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) 1004 { 1005 struct cx8802_dev *dev = video_drvdata(file); 1006 struct cx88_core *core = dev->core; 1007 1008 return cx88_set_tvnorm(core, id); 1009 } 1010 1011 static const struct v4l2_file_operations mpeg_fops = 1012 { 1013 .owner = THIS_MODULE, 1014 .open = v4l2_fh_open, 1015 .release = vb2_fop_release, 1016 .read = vb2_fop_read, 1017 .poll = vb2_fop_poll, 1018 .mmap = vb2_fop_mmap, 1019 .unlocked_ioctl = video_ioctl2, 1020 }; 1021 1022 static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { 1023 .vidioc_querycap = vidioc_querycap, 1024 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 1025 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 1026 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 1027 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 1028 .vidioc_reqbufs = vb2_ioctl_reqbufs, 1029 .vidioc_querybuf = vb2_ioctl_querybuf, 1030 .vidioc_qbuf = vb2_ioctl_qbuf, 1031 .vidioc_dqbuf = vb2_ioctl_dqbuf, 1032 .vidioc_streamon = vb2_ioctl_streamon, 1033 .vidioc_streamoff = vb2_ioctl_streamoff, 1034 .vidioc_s_frequency = vidioc_s_frequency, 1035 .vidioc_log_status = vidioc_log_status, 1036 .vidioc_enum_input = vidioc_enum_input, 1037 .vidioc_g_frequency = vidioc_g_frequency, 1038 .vidioc_g_input = vidioc_g_input, 1039 .vidioc_s_input = vidioc_s_input, 1040 .vidioc_g_tuner = vidioc_g_tuner, 1041 .vidioc_s_tuner = vidioc_s_tuner, 1042 .vidioc_g_std = vidioc_g_std, 1043 .vidioc_s_std = vidioc_s_std, 1044 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 1045 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 1046 }; 1047 1048 static struct video_device cx8802_mpeg_template = { 1049 .name = "cx8802", 1050 .fops = &mpeg_fops, 1051 .ioctl_ops = &mpeg_ioctl_ops, 1052 .tvnorms = CX88_NORMS, 1053 }; 1054 1055 /* ------------------------------------------------------------------ */ 1056 1057 /* The CX8802 MPEG API will call this when we can use the hardware */ 1058 static int cx8802_blackbird_advise_acquire(struct cx8802_driver *drv) 1059 { 1060 struct cx88_core *core = drv->core; 1061 int err = 0; 1062 1063 switch (core->boardnr) { 1064 case CX88_BOARD_HAUPPAUGE_HVR1300: 1065 /* By default, core setup will leave the cx22702 out of reset, on the bus. 1066 * We left the hardware on power up with the cx22702 active. 1067 * We're being given access to re-arrange the GPIOs. 1068 * Take the bus off the cx22702 and put the cx23416 on it. 1069 */ 1070 /* Toggle reset on cx22702 leaving i2c active */ 1071 cx_set(MO_GP0_IO, 0x00000080); 1072 udelay(1000); 1073 cx_clear(MO_GP0_IO, 0x00000080); 1074 udelay(50); 1075 cx_set(MO_GP0_IO, 0x00000080); 1076 udelay(1000); 1077 /* tri-state the cx22702 pins */ 1078 cx_set(MO_GP0_IO, 0x00000004); 1079 udelay(1000); 1080 break; 1081 default: 1082 err = -ENODEV; 1083 } 1084 return err; 1085 } 1086 1087 /* The CX8802 MPEG API will call this when we need to release the hardware */ 1088 static int cx8802_blackbird_advise_release(struct cx8802_driver *drv) 1089 { 1090 struct cx88_core *core = drv->core; 1091 int err = 0; 1092 1093 switch (core->boardnr) { 1094 case CX88_BOARD_HAUPPAUGE_HVR1300: 1095 /* Exit leaving the cx23416 on the bus */ 1096 break; 1097 default: 1098 err = -ENODEV; 1099 } 1100 return err; 1101 } 1102 1103 static void blackbird_unregister_video(struct cx8802_dev *dev) 1104 { 1105 video_unregister_device(&dev->mpeg_dev); 1106 } 1107 1108 static int blackbird_register_video(struct cx8802_dev *dev) 1109 { 1110 int err; 1111 1112 cx88_vdev_init(dev->core, dev->pci, &dev->mpeg_dev, 1113 &cx8802_mpeg_template, "mpeg"); 1114 dev->mpeg_dev.ctrl_handler = &dev->cxhdl.hdl; 1115 video_set_drvdata(&dev->mpeg_dev, dev); 1116 dev->mpeg_dev.queue = &dev->vb2_mpegq; 1117 err = video_register_device(&dev->mpeg_dev, VFL_TYPE_GRABBER, -1); 1118 if (err < 0) { 1119 printk(KERN_INFO "%s/2: can't register mpeg device\n", 1120 dev->core->name); 1121 return err; 1122 } 1123 printk(KERN_INFO "%s/2: registered device %s [mpeg]\n", 1124 dev->core->name, video_device_node_name(&dev->mpeg_dev)); 1125 return 0; 1126 } 1127 1128 /* ----------------------------------------------------------- */ 1129 1130 static int cx8802_blackbird_probe(struct cx8802_driver *drv) 1131 { 1132 struct cx88_core *core = drv->core; 1133 struct cx8802_dev *dev = core->dvbdev; 1134 struct vb2_queue *q; 1135 int err; 1136 1137 dprintk( 1, "%s\n", __func__); 1138 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", 1139 core->boardnr, 1140 core->name, 1141 core->pci_bus, 1142 core->pci_slot); 1143 1144 err = -ENODEV; 1145 if (!(core->board.mpeg & CX88_MPEG_BLACKBIRD)) 1146 goto fail_core; 1147 1148 dev->cxhdl.port = CX2341X_PORT_STREAMING; 1149 dev->cxhdl.width = core->width; 1150 dev->cxhdl.height = core->height; 1151 dev->cxhdl.func = blackbird_mbox_func; 1152 dev->cxhdl.priv = dev; 1153 err = cx2341x_handler_init(&dev->cxhdl, 36); 1154 if (err) 1155 goto fail_core; 1156 v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl, NULL); 1157 1158 /* blackbird stuff */ 1159 printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n", 1160 core->name); 1161 host_setup(dev->core); 1162 1163 blackbird_initialize_codec(dev); 1164 1165 /* initial device configuration: needed ? */ 1166 // init_controls(core); 1167 cx88_set_tvnorm(core,core->tvnorm); 1168 cx88_video_mux(core,0); 1169 cx2341x_handler_set_50hz(&dev->cxhdl, core->height == 576); 1170 cx2341x_handler_setup(&dev->cxhdl); 1171 1172 q = &dev->vb2_mpegq; 1173 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1174 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; 1175 q->gfp_flags = GFP_DMA32; 1176 q->min_buffers_needed = 2; 1177 q->drv_priv = dev; 1178 q->buf_struct_size = sizeof(struct cx88_buffer); 1179 q->ops = &blackbird_qops; 1180 q->mem_ops = &vb2_dma_sg_memops; 1181 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1182 q->lock = &core->lock; 1183 1184 err = vb2_queue_init(q); 1185 if (err < 0) 1186 goto fail_core; 1187 1188 blackbird_register_video(dev); 1189 1190 return 0; 1191 1192 fail_core: 1193 return err; 1194 } 1195 1196 static int cx8802_blackbird_remove(struct cx8802_driver *drv) 1197 { 1198 struct cx88_core *core = drv->core; 1199 struct cx8802_dev *dev = core->dvbdev; 1200 1201 /* blackbird */ 1202 blackbird_unregister_video(drv->core->dvbdev); 1203 v4l2_ctrl_handler_free(&dev->cxhdl.hdl); 1204 1205 return 0; 1206 } 1207 1208 static struct cx8802_driver cx8802_blackbird_driver = { 1209 .type_id = CX88_MPEG_BLACKBIRD, 1210 .hw_access = CX8802_DRVCTL_SHARED, 1211 .probe = cx8802_blackbird_probe, 1212 .remove = cx8802_blackbird_remove, 1213 .advise_acquire = cx8802_blackbird_advise_acquire, 1214 .advise_release = cx8802_blackbird_advise_release, 1215 }; 1216 1217 static int __init blackbird_init(void) 1218 { 1219 printk(KERN_INFO "cx2388x blackbird driver version %s loaded\n", 1220 CX88_VERSION); 1221 return cx8802_register_driver(&cx8802_blackbird_driver); 1222 } 1223 1224 static void __exit blackbird_fini(void) 1225 { 1226 cx8802_unregister_driver(&cx8802_blackbird_driver); 1227 } 1228 1229 module_init(blackbird_init); 1230 module_exit(blackbird_fini); 1231