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