3 * Support for a cx23416 mpeg encoder via cx2388x host port.
4 * "blackbird" reference design.
6 * (c) 2004 Jelle Foks <jelle@foks.8m.com>
7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
9 * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/),
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <linux/module.h>
27 #include <linux/moduleparam.h>
28 #include <linux/init.h>
30 #include <linux/delay.h>
31 #include <linux/device.h>
32 #include <linux/firmware.h>
36 MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards");
37 MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
38 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39 MODULE_LICENSE("GPL");
41 static unsigned int mpegbufs
= 32;
42 module_param(mpegbufs
,int,0644);
43 MODULE_PARM_DESC(mpegbufs
,"number of mpeg buffers, range 2-32");
45 static unsigned int debug
= 0;
46 module_param(debug
,int,0644);
47 MODULE_PARM_DESC(debug
,"enable debug messages [blackbird]");
49 #define dprintk(level,fmt, arg...) if (debug >= level) \
50 printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg)
52 static LIST_HEAD(cx8802_devlist
);
54 /* ------------------------------------------------------------------ */
56 #define BLACKBIRD_FIRM_ENC_FILENAME "blackbird-fw-enc.bin"
57 #define BLACKBIRD_FIRM_IMAGE_SIZE 256*1024
59 /* defines below are from ivtv-driver.h */
61 #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
63 /* Firmware API commands */
64 #define IVTV_API_STD_TIMEOUT 500
66 #define BLACKBIRD_API_PING 0x80
67 #define BLACKBIRD_API_BEGIN_CAPTURE 0x81
68 enum blackbird_capture_type
{
69 BLACKBIRD_MPEG_CAPTURE
,
70 BLACKBIRD_RAW_CAPTURE
,
71 BLACKBIRD_RAW_PASSTHRU_CAPTURE
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
81 #define BLACKBIRD_API_END_CAPTURE 0x82
82 enum blackbird_capture_end
{
83 BLACKBIRD_END_AT_GOP
, /* stop at the end of gop, generate irq */
84 BLACKBIRD_END_NOW
, /* stop immediately, no irq */
86 #define BLACKBIRD_API_SET_AUDIO_ID 0x89
87 #define BLACKBIRD_API_SET_VIDEO_ID 0x8B
88 #define BLACKBIRD_API_SET_PCR_ID 0x8D
89 #define BLACKBIRD_API_SET_FRAMERATE 0x8F
90 enum blackbird_framerate
{
91 BLACKBIRD_FRAMERATE_NTSC_30
, /* NTSC: 30fps */
92 BLACKBIRD_FRAMERATE_PAL_25
/* PAL: 25fps */
94 #define BLACKBIRD_API_SET_RESOLUTION 0x91
95 #define BLACKBIRD_API_SET_VIDEO_BITRATE 0x95
96 enum blackbird_video_bitrate_type
{
100 #define BLACKBIRD_PEAK_RATE_DIVISOR 400
101 enum blackbird_mux_rate
{
102 BLACKBIRD_MUX_RATE_DEFAULT
,
103 /* dvd mux rate: multiply by 400 to get the actual rate */
104 BLACKBIRD_MUX_RATE_DVD
= 25200
106 #define BLACKBIRD_API_SET_GOP_STRUCTURE 0x97
107 #define BLACKBIRD_API_SET_ASPECT_RATIO 0x99
108 enum blackbird_aspect_ratio
{
109 BLACKBIRD_ASPECT_RATIO_FORBIDDEN
,
110 BLACKBIRD_ASPECT_RATIO_1_1_SQUARE
,
111 BLACKBIRD_ASPECT_RATIO_4_3
,
112 BLACKBIRD_ASPECT_RATIO_16_9
,
113 BLACKBIRD_ASPECT_RATIO_221_100
,
114 BLACKBIRD_ASPECT_RATIO_RESERVED
116 #define BLACKBIRD_API_SET_DNR_MODE 0x9B
117 enum blackbird_dnr_bits
{
118 BLACKBIRD_DNR_BITS_MANUAL
,
119 BLACKBIRD_DNR_BITS_AUTO_SPATIAL
,
120 BLACKBIRD_DNR_BITS_AUTO_TEMPORAL
,
121 BLACKBIRD_DNR_BITS_AUTO
123 enum blackbird_median_filter
{
124 BLACKBIRD_MEDIAN_FILTER_DISABLED
,
125 BLACKBIRD_MEDIAN_FILTER_HORIZONTAL
,
126 BLACKBIRD_MEDIAN_FILTER_VERTICAL
,
127 BLACKBIRD_MEDIAN_FILTER_HV
,
128 BLACKBIRD_MEDIAN_FILTER_DIAGONAL
130 #define BLACKBIRD_API_SET_MANUAL_DNR 0x9D
131 #define BLACKBIRD_API_SET_DNR_MEDIAN 0x9F
132 #define BLACKBIRD_API_SET_SPATIAL_FILTER 0xA1
133 enum blackbird_spatial_filter_luma
{
134 BLACKBIRD_SPATIAL_FILTER_LUMA_DISABLED
,
135 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ
,
136 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_VERT
,
137 BLACKBIRD_SPATIAL_FILTER_LUMA_2D_HV
, /* separable, default */
138 BLACKBIRD_SPATIAL_FILTER_LUMA_2D_SYMM
/* symmetric non-separable */
140 enum blackbird_spatial_filter_chroma
{
141 BLACKBIRD_SPATIAL_FILTER_CHROMA_DISABLED
,
142 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
/* default */
144 #define BLACKBIRD_API_SET_3_2_PULLDOWN 0xB1
145 enum blackbird_pulldown
{
146 BLACKBIRD_3_2_PULLDOWN_DISABLED
,
147 BLACKBIRD_3_2_PULLDOWN_ENABLED
149 #define BLACKBIRD_API_SET_VBI_LINE_NO 0xB7
150 enum blackbird_vbi_line_bits
{
151 BLACKBIRD_VBI_LINE_BITS_TOP_FIELD
,
152 BLACKBIRD_VBI_LINE_BITS_BOT_FIELD
= (1 << 31),
153 BLACKBIRD_VBI_LINE_BITS_ALL_LINES
= 0xFFFFFFFF
155 enum blackbird_vbi_line
{
156 BLACKBIRD_VBI_LINE_DISABLED
,
157 BLACKBIRD_VBI_LINE_ENABLED
159 enum blackbird_vbi_slicing
{
160 BLACKBIRD_VBI_SLICING_NONE
,
161 BLACKBIRD_VBI_SLICING_CLOSED_CAPTION
163 #define BLACKBIRD_API_SET_STREAM_TYPE 0xB9
164 enum blackbird_stream_type
{
165 BLACKBIRD_STREAM_PROGRAM
,
166 BLACKBIRD_STREAM_TRANSPORT
,
167 BLACKBIRD_STREAM_MPEG1
,
168 BLACKBIRD_STREAM_PES_AV
,
169 BLACKBIRD_STREAM_UNKNOWN4
,
170 BLACKBIRD_STREAM_PES_VIDEO
,
171 BLACKBIRD_STREAM_UNKNOWN6
,
172 BLACKBIRD_STREAM_PES_AUDIO
,
173 BLACKBIRD_STREAM_UNKNOWN8
,
174 BLACKBIRD_STREAM_UNKNOWN9
, /* audio/pcm ? */
175 BLACKBIRD_STREAM_DVD
,
176 BLACKBIRD_STREAM_VCD
,
177 BLACKBIRD_STREAM_UNKNOWN12
/* svcd/xvcd ? */
179 #define BLACKBIRD_API_SET_OUTPUT_PORT 0xBB
180 enum blackbird_stream_port
{
181 BLACKBIRD_OUTPUT_PORT_MEMORY
,
182 BLACKBIRD_OUTPUT_PORT_STREAMING
,
183 BLACKBIRD_OUTPUT_PORT_SERIAL
185 #define BLACKBIRD_API_SET_AUDIO_PARAMS 0xBD
186 enum blackbird_audio_bits_sample_rate
{
187 BLACKBIRD_AUDIO_BITS_44100HZ
,
188 BLACKBIRD_AUDIO_BITS_48000HZ
,
189 BLACKBIRD_AUDIO_BITS_32000HZ
,
190 BLACKBIRD_AUDIO_BITS_RESERVED_HZ
,
192 enum blackbird_audio_bits_encoding
{
193 BLACKBIRD_AUDIO_BITS_LAYER_1
= 0x1 << 2,
194 BLACKBIRD_AUDIO_BITS_LAYER_2
= 0x2 << 2,
196 enum blackbird_audio_bits_bitrate_layer_1
{
197 BLACKBIRD_AUDIO_BITS_LAYER_1_FREE_FORMAT
,
198 BLACKBIRD_AUDIO_BITS_LAYER_1_32
= 0x01 << 4,
199 BLACKBIRD_AUDIO_BITS_LAYER_1_64
= 0x02 << 4,
200 BLACKBIRD_AUDIO_BITS_LAYER_1_96
= 0x03 << 4,
201 BLACKBIRD_AUDIO_BITS_LAYER_1_128
= 0x04 << 4,
202 BLACKBIRD_AUDIO_BITS_LAYER_1_160
= 0x05 << 4,
203 BLACKBIRD_AUDIO_BITS_LAYER_1_192
= 0x06 << 4,
204 BLACKBIRD_AUDIO_BITS_LAYER_1_224
= 0x07 << 4,
205 BLACKBIRD_AUDIO_BITS_LAYER_1_256
= 0x08 << 4,
206 BLACKBIRD_AUDIO_BITS_LAYER_1_288
= 0x09 << 4,
207 BLACKBIRD_AUDIO_BITS_LAYER_1_320
= 0x0A << 4,
208 BLACKBIRD_AUDIO_BITS_LAYER_1_352
= 0x0B << 4,
209 BLACKBIRD_AUDIO_BITS_LAYER_1_384
= 0x0C << 4,
210 BLACKBIRD_AUDIO_BITS_LAYER_1_416
= 0x0D << 4,
211 BLACKBIRD_AUDIO_BITS_LAYER_1_448
= 0x0E << 4,
213 enum blackbird_audio_bits_bitrate_layer_2
{
214 BLACKBIRD_AUDIO_BITS_LAYER_2_FREE_FORMAT
,
215 BLACKBIRD_AUDIO_BITS_LAYER_2_32
= 0x01 << 4,
216 BLACKBIRD_AUDIO_BITS_LAYER_2_48
= 0x02 << 4,
217 BLACKBIRD_AUDIO_BITS_LAYER_2_56
= 0x03 << 4,
218 BLACKBIRD_AUDIO_BITS_LAYER_2_64
= 0x04 << 4,
219 BLACKBIRD_AUDIO_BITS_LAYER_2_80
= 0x05 << 4,
220 BLACKBIRD_AUDIO_BITS_LAYER_2_96
= 0x06 << 4,
221 BLACKBIRD_AUDIO_BITS_LAYER_2_112
= 0x07 << 4,
222 BLACKBIRD_AUDIO_BITS_LAYER_2_128
= 0x08 << 4,
223 BLACKBIRD_AUDIO_BITS_LAYER_2_160
= 0x09 << 4,
224 BLACKBIRD_AUDIO_BITS_LAYER_2_192
= 0x0A << 4,
225 BLACKBIRD_AUDIO_BITS_LAYER_2_224
= 0x0B << 4,
226 BLACKBIRD_AUDIO_BITS_LAYER_2_256
= 0x0C << 4,
227 BLACKBIRD_AUDIO_BITS_LAYER_2_320
= 0x0D << 4,
228 BLACKBIRD_AUDIO_BITS_LAYER_2_384
= 0x0E << 4,
230 enum blackbird_audio_bits_mode
{
231 BLACKBIRD_AUDIO_BITS_STEREO
,
232 BLACKBIRD_AUDIO_BITS_JOINT_STEREO
= 0x1 << 8,
233 BLACKBIRD_AUDIO_BITS_DUAL
= 0x2 << 8,
234 BLACKBIRD_AUDIO_BITS_MONO
= 0x3 << 8,
236 enum blackbird_audio_bits_mode_extension
{
237 BLACKBIRD_AUDIO_BITS_BOUND_4
,
238 BLACKBIRD_AUDIO_BITS_BOUND_8
= 0x1 << 10,
239 BLACKBIRD_AUDIO_BITS_BOUND_12
= 0x2 << 10,
240 BLACKBIRD_AUDIO_BITS_BOUND_16
= 0x3 << 10,
242 enum blackbird_audio_bits_emphasis
{
243 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE
,
244 BLACKBIRD_AUDIO_BITS_EMPHASIS_50_15
= 0x1 << 12,
245 BLACKBIRD_AUDIO_BITS_EMPHASIS_RESERVED
= 0x2 << 12,
246 BLACKBIRD_AUDIO_BITS_EMPHASIS_CCITT_J17
= 0x3 << 12,
248 enum blackbird_audio_bits_crc
{
249 BLACKBIRD_AUDIO_BITS_CRC_OFF
,
250 BLACKBIRD_AUDIO_BITS_CRC_ON
= 0x1 << 14,
252 enum blackbird_audio_bits_copyright
{
253 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF
,
254 BLACKBIRD_AUDIO_BITS_COPYRIGHT_ON
= 0x1 << 15,
256 enum blackbird_audio_bits_original
{
257 BLACKBIRD_AUDIO_BITS_COPY
,
258 BLACKBIRD_AUDIO_BITS_ORIGINAL
= 0x1 << 16,
260 #define BLACKBIRD_API_HALT 0xC3
261 #define BLACKBIRD_API_GET_VERSION 0xC4
262 #define BLACKBIRD_API_SET_GOP_CLOSURE 0xC5
263 enum blackbird_gop_closure
{
264 BLACKBIRD_GOP_CLOSURE_OFF
,
265 BLACKBIRD_GOP_CLOSURE_ON
,
267 #define BLACKBIRD_API_DATA_XFER_STATUS 0xC6
268 enum blackbird_data_xfer_status
{
269 BLACKBIRD_MORE_BUFFERS_FOLLOW
,
270 BLACKBIRD_LAST_BUFFER
,
272 #define BLACKBIRD_API_PROGRAM_INDEX_INFO 0xC7
273 enum blackbird_picture_mask
{
274 BLACKBIRD_PICTURE_MASK_NONE
,
275 BLACKBIRD_PICTURE_MASK_I_FRAMES
,
276 BLACKBIRD_PICTURE_MASK_I_P_FRAMES
= 0x3,
277 BLACKBIRD_PICTURE_MASK_ALL_FRAMES
= 0x7,
279 #define BLACKBIRD_API_SET_VBI_PARAMS 0xC8
280 enum blackbird_vbi_mode_bits
{
281 BLACKBIRD_VBI_BITS_SLICED
,
282 BLACKBIRD_VBI_BITS_RAW
,
284 enum blackbird_vbi_insertion_bits
{
285 BLACKBIRD_VBI_BITS_INSERT_IN_XTENSION_USR_DATA
,
286 BLACKBIRD_VBI_BITS_INSERT_IN_PRIVATE_PACKETS
= 0x1 << 1,
287 BLACKBIRD_VBI_BITS_SEPARATE_STREAM
= 0x2 << 1,
288 BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA
= 0x4 << 1,
289 BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA
= 0x5 << 1,
291 #define BLACKBIRD_API_SET_DMA_BLOCK_SIZE 0xC9
292 enum blackbird_dma_unit
{
294 BLACKBIRD_DMA_FRAMES
,
296 #define BLACKBIRD_API_DMA_TRANSFER_INFO 0xCA
297 #define BLACKBIRD_API_DMA_TRANSFER_STAT 0xCB
298 enum blackbird_dma_transfer_status_bits
{
299 BLACKBIRD_DMA_TRANSFER_BITS_DONE
= 0x01,
300 BLACKBIRD_DMA_TRANSFER_BITS_ERROR
= 0x04,
301 BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR
= 0x10,
303 #define BLACKBIRD_API_SET_DMA2HOST_ADDR 0xCC
304 #define BLACKBIRD_API_INIT_VIDEO_INPUT 0xCD
305 #define BLACKBIRD_API_SET_FRAMESKIP 0xD0
306 #define BLACKBIRD_API_PAUSE 0xD2
307 enum blackbird_pause
{
308 BLACKBIRD_PAUSE_ENCODING
,
309 BLACKBIRD_RESUME_ENCODING
,
311 #define BLACKBIRD_API_REFRESH_INPUT 0xD3
312 #define BLACKBIRD_API_SET_COPYRIGHT 0xD4
313 enum blackbird_copyright
{
314 BLACKBIRD_COPYRIGHT_OFF
,
315 BLACKBIRD_COPYRIGHT_ON
,
317 #define BLACKBIRD_API_SET_NOTIFICATION 0xD5
318 enum blackbird_notification_type
{
319 BLACKBIRD_NOTIFICATION_REFRESH
,
321 enum blackbird_notification_status
{
322 BLACKBIRD_NOTIFICATION_OFF
,
323 BLACKBIRD_NOTIFICATION_ON
,
325 enum blackbird_notification_mailbox
{
326 BLACKBIRD_NOTIFICATION_NO_MAILBOX
= -1,
328 #define BLACKBIRD_API_SET_CAPTURE_LINES 0xD6
329 enum blackbird_field1_lines
{
330 BLACKBIRD_FIELD1_SAA7114
= 0x00EF, /* 239 */
331 BLACKBIRD_FIELD1_SAA7115
= 0x00F0, /* 240 */
332 BLACKBIRD_FIELD1_MICRONAS
= 0x0105, /* 261 */
334 enum blackbird_field2_lines
{
335 BLACKBIRD_FIELD2_SAA7114
= 0x00EF, /* 239 */
336 BLACKBIRD_FIELD2_SAA7115
= 0x00F0, /* 240 */
337 BLACKBIRD_FIELD2_MICRONAS
= 0x0106, /* 262 */
339 #define BLACKBIRD_API_SET_CUSTOM_DATA 0xD7
340 enum blackbird_custom_data_type
{
341 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA
,
342 BLACKBIRD_CUSTOM_PRIVATE_PACKET
,
344 #define BLACKBIRD_API_MUTE_VIDEO 0xD9
345 enum blackbird_mute
{
349 enum blackbird_mute_video_mask
{
350 BLACKBIRD_MUTE_VIDEO_V_MASK
= 0x0000FF00,
351 BLACKBIRD_MUTE_VIDEO_U_MASK
= 0x00FF0000,
352 BLACKBIRD_MUTE_VIDEO_Y_MASK
= 0xFF000000,
354 enum blackbird_mute_video_shift
{
355 BLACKBIRD_MUTE_VIDEO_V_SHIFT
= 8,
356 BLACKBIRD_MUTE_VIDEO_U_SHIFT
= 16,
357 BLACKBIRD_MUTE_VIDEO_Y_SHIFT
= 24,
359 #define BLACKBIRD_API_MUTE_AUDIO 0xDA
362 #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/)
363 #define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC /*| IVTV_REG_OFFSET*/)
364 #define IVTV_REG_SPU (0x9050 /*| IVTV_REG_OFFSET*/)
365 #define IVTV_REG_HW_BLOCKS (0x9054 /*| IVTV_REG_OFFSET*/)
366 #define IVTV_REG_VPU (0x9058 /*| IVTV_REG_OFFSET*/)
367 #define IVTV_REG_APU (0xA064 /*| IVTV_REG_OFFSET*/)
369 /* ------------------------------------------------------------------ */
371 static void host_setup(struct cx88_core
*core
)
373 /* toggle reset of the host */
374 cx_write(MO_GPHST_SOFT_RST
, 1);
376 cx_write(MO_GPHST_SOFT_RST
, 0);
379 /* host port setup */
380 cx_write(MO_GPHST_WSC
, 0x44444444U
);
381 cx_write(MO_GPHST_XFR
, 0);
382 cx_write(MO_GPHST_WDTH
, 15);
383 cx_write(MO_GPHST_HDSHK
, 0);
384 cx_write(MO_GPHST_MUX16
, 0x44448888U
);
385 cx_write(MO_GPHST_MODE
, 0);
388 /* ------------------------------------------------------------------ */
390 #define P1_MDATA0 0x390000
391 #define P1_MDATA1 0x390001
392 #define P1_MDATA2 0x390002
393 #define P1_MDATA3 0x390003
394 #define P1_MADDR2 0x390004
395 #define P1_MADDR1 0x390005
396 #define P1_MADDR0 0x390006
397 #define P1_RDATA0 0x390008
398 #define P1_RDATA1 0x390009
399 #define P1_RDATA2 0x39000A
400 #define P1_RDATA3 0x39000B
401 #define P1_RADDR0 0x39000C
402 #define P1_RADDR1 0x39000D
403 #define P1_RRDWR 0x39000E
405 static int wait_ready_gpio0_bit1(struct cx88_core
*core
, u32 state
)
407 unsigned long timeout
= jiffies
+ msecs_to_jiffies(1);
410 need
= state
? 2 : 0;
412 gpio0
= cx_read(MO_GP0_IO
) & 2;
415 if (time_after(jiffies
,timeout
))
421 static int memory_write(struct cx88_core
*core
, u32 address
, u32 value
)
423 /* Warning: address is dword address (4 bytes) */
424 cx_writeb(P1_MDATA0
, (unsigned int)value
);
425 cx_writeb(P1_MDATA1
, (unsigned int)(value
>> 8));
426 cx_writeb(P1_MDATA2
, (unsigned int)(value
>> 16));
427 cx_writeb(P1_MDATA3
, (unsigned int)(value
>> 24));
428 cx_writeb(P1_MADDR2
, (unsigned int)(address
>> 16) | 0x40);
429 cx_writeb(P1_MADDR1
, (unsigned int)(address
>> 8));
430 cx_writeb(P1_MADDR0
, (unsigned int)address
);
434 return wait_ready_gpio0_bit1(core
,1);
437 static int memory_read(struct cx88_core
*core
, u32 address
, u32
*value
)
442 /* Warning: address is dword address (4 bytes) */
443 cx_writeb(P1_MADDR2
, (unsigned int)(address
>> 16) & ~0xC0);
444 cx_writeb(P1_MADDR1
, (unsigned int)(address
>> 8));
445 cx_writeb(P1_MADDR0
, (unsigned int)address
);
448 retval
= wait_ready_gpio0_bit1(core
,1);
450 cx_writeb(P1_MDATA3
, 0);
451 val
= (unsigned char)cx_read(P1_MDATA3
) << 24;
452 cx_writeb(P1_MDATA2
, 0);
453 val
|= (unsigned char)cx_read(P1_MDATA2
) << 16;
454 cx_writeb(P1_MDATA1
, 0);
455 val
|= (unsigned char)cx_read(P1_MDATA1
) << 8;
456 cx_writeb(P1_MDATA0
, 0);
457 val
|= (unsigned char)cx_read(P1_MDATA0
);
463 static int register_write(struct cx88_core
*core
, u32 address
, u32 value
)
465 cx_writeb(P1_RDATA0
, (unsigned int)value
);
466 cx_writeb(P1_RDATA1
, (unsigned int)(value
>> 8));
467 cx_writeb(P1_RDATA2
, (unsigned int)(value
>> 16));
468 cx_writeb(P1_RDATA3
, (unsigned int)(value
>> 24));
469 cx_writeb(P1_RADDR0
, (unsigned int)address
);
470 cx_writeb(P1_RADDR1
, (unsigned int)(address
>> 8));
471 cx_writeb(P1_RRDWR
, 1);
475 return wait_ready_gpio0_bit1(core
,1);
479 static int register_read(struct cx88_core
*core
, u32 address
, u32
*value
)
484 cx_writeb(P1_RADDR0
, (unsigned int)address
);
485 cx_writeb(P1_RADDR1
, (unsigned int)(address
>> 8));
486 cx_writeb(P1_RRDWR
, 0);
489 retval
= wait_ready_gpio0_bit1(core
,1);
490 val
= (unsigned char)cx_read(P1_RDATA0
);
491 val
|= (unsigned char)cx_read(P1_RDATA1
) << 8;
492 val
|= (unsigned char)cx_read(P1_RDATA2
) << 16;
493 val
|= (unsigned char)cx_read(P1_RDATA3
) << 24;
499 /* ------------------------------------------------------------------ */
501 /* We don't need to call the API often, so using just one mailbox will probably suffice */
502 static int blackbird_api_cmd(struct cx8802_dev
*dev
, u32 command
,
503 u32 inputcnt
, u32 outputcnt
, ...)
505 unsigned long timeout
;
506 u32 value
, flag
, retval
;
509 va_start(args
, outputcnt
);
511 dprintk(1,"%s: 0x%X\n", __FUNCTION__
, command
);
513 /* this may not be 100% safe if we can't read any memory location
514 without side effects */
515 memory_read(dev
->core
, dev
->mailbox
- 4, &value
);
516 if (value
!= 0x12345678) {
517 dprintk(0, "Firmware and/or mailbox pointer not initialized or corrupted\n");
521 memory_read(dev
->core
, dev
->mailbox
, &flag
);
523 dprintk(0, "ERROR: Mailbox appears to be in use (%x)\n", flag
);
527 flag
|= 1; /* tell 'em we're working on it */
528 memory_write(dev
->core
, dev
->mailbox
, flag
);
530 /* write command + args + fill remaining with zeros */
531 memory_write(dev
->core
, dev
->mailbox
+ 1, command
); /* command code */
532 memory_write(dev
->core
, dev
->mailbox
+ 3, IVTV_API_STD_TIMEOUT
); /* timeout */
533 for (i
= 0; i
< inputcnt
; i
++) {
534 value
= va_arg(args
, int);
535 memory_write(dev
->core
, dev
->mailbox
+ 4 + i
, value
);
536 dprintk(1, "API Input %d = %d\n", i
, value
);
539 memory_write(dev
->core
, dev
->mailbox
+ 4 + i
, 0);
541 flag
|= 3; /* tell 'em we're done writing */
542 memory_write(dev
->core
, dev
->mailbox
, flag
);
544 /* wait for firmware to handle the API command */
545 timeout
= jiffies
+ msecs_to_jiffies(10);
547 memory_read(dev
->core
, dev
->mailbox
, &flag
);
550 if (time_after(jiffies
,timeout
)) {
551 dprintk(0, "ERROR: API Mailbox timeout\n");
557 /* read output values */
558 for (i
= 0; i
< outputcnt
; i
++) {
559 int *vptr
= va_arg(args
, int *);
560 memory_read(dev
->core
, dev
->mailbox
+ 4 + i
, vptr
);
561 dprintk(1, "API Output %d = %d\n", i
, *vptr
);
565 memory_read(dev
->core
, dev
->mailbox
+ 2, &retval
);
566 dprintk(1, "API result = %d\n",retval
);
569 memory_write(dev
->core
, dev
->mailbox
, flag
);
574 static int blackbird_find_mailbox(struct cx8802_dev
*dev
)
576 u32 signature
[4]={0x12345678, 0x34567812, 0x56781234, 0x78123456};
581 for (i
= 0; i
< BLACKBIRD_FIRM_IMAGE_SIZE
; i
++) {
582 memory_read(dev
->core
, i
, &value
);
583 if (value
== signature
[signaturecnt
])
587 if (4 == signaturecnt
) {
588 dprintk(1, "Mailbox signature found\n");
592 dprintk(0, "Mailbox signature values not found!\n");
596 static int blackbird_load_firmware(struct cx8802_dev
*dev
)
598 static const unsigned char magic
[8] = {
599 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
601 const struct firmware
*firmware
;
607 retval
= register_write(dev
->core
, IVTV_REG_VPU
, 0xFFFFFFED);
608 retval
|= register_write(dev
->core
, IVTV_REG_HW_BLOCKS
, IVTV_CMD_HW_BLOCKS_RST
);
609 retval
|= register_write(dev
->core
, IVTV_REG_ENC_SDRAM_REFRESH
, 0x80000640);
610 retval
|= register_write(dev
->core
, IVTV_REG_ENC_SDRAM_PRECHARGE
, 0x1A);
612 retval
|= register_write(dev
->core
, IVTV_REG_APU
, 0);
615 dprintk(0, "Error with register_write\n");
617 retval
= request_firmware(&firmware
, BLACKBIRD_FIRM_ENC_FILENAME
,
622 dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n",
623 BLACKBIRD_FIRM_ENC_FILENAME
);
624 dprintk(0, "Please fix your hotplug setup, the board will "
625 "not work without firmware loaded!\n");
629 if (firmware
->size
!= BLACKBIRD_FIRM_IMAGE_SIZE
) {
630 dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n",
631 firmware
->size
, BLACKBIRD_FIRM_IMAGE_SIZE
);
635 if (0 != memcmp(firmware
->data
, magic
, 8)) {
636 dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n");
640 /* transfer to the chip */
641 dprintk(1,"Loading firmware ...\n");
642 dataptr
= (u32
*)firmware
->data
;
643 for (i
= 0; i
< (firmware
->size
>> 2); i
++) {
646 memory_write(dev
->core
, i
, value
);
650 /* read back to verify with the checksum */
651 for (i
--; i
>= 0; i
--) {
652 memory_read(dev
->core
, i
, &value
);
656 dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n");
659 release_firmware(firmware
);
660 dprintk(0, "Firmware upload successful.\n");
662 retval
|= register_write(dev
->core
, IVTV_REG_HW_BLOCKS
, IVTV_CMD_HW_BLOCKS_RST
);
663 retval
|= register_read(dev
->core
, IVTV_REG_SPU
, &value
);
664 retval
|= register_write(dev
->core
, IVTV_REG_SPU
, value
& 0xFFFFFFFE);
667 retval
|= register_read(dev
->core
, IVTV_REG_VPU
, &value
);
668 retval
|= register_write(dev
->core
, IVTV_REG_VPU
, value
& 0xFFFFFFE8);
671 dprintk(0, "Error with register_write\n");
676 Settings used by the windows tv app for PVR2000:
677 =================================================================================================================
678 Profile | Codec | Resolution | CBR/VBR | Video Qlty | V. Bitrate | Frmrate | Audio Codec | A. Bitrate | A. Mode
679 -----------------------------------------------------------------------------------------------------------------
680 MPEG-1 | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 2000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
681 MPEG-2 | MPEG2 | 720x576PAL | VBR | 600 :Good | 4000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
682 VCD | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 1150 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
683 DVD | MPEG2 | 720x576PAL | VBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
684 DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
685 =================================================================================================================
689 static struct blackbird_dnr default_dnr_params
= {
690 .mode
= BLACKBIRD_DNR_BITS_MANUAL
,
691 .type
= BLACKBIRD_MEDIAN_FILTER_DISABLED
,
695 static struct v4l2_mpeg_compression default_mpeg_params
= {
696 .st_type
= V4L2_MPEG_PS_2
,
698 .mode
= V4L2_BITRATE_CBR
,
708 .au_type
= V4L2_MPEG_AU_2_II
,
710 .mode
= V4L2_BITRATE_CBR
,
715 .au_sample_rate
= 44100,
717 .vi_type
= V4L2_MPEG_VI_2
,
718 .vi_aspect_ratio
= V4L2_MPEG_ASPECT_4_3
,
720 .mode
= V4L2_BITRATE_CBR
,
726 .vi_frames_per_gop
= 15,
727 .vi_bframes_count
= 2,
733 static enum blackbird_stream_type mpeg_stream_types
[] = {
734 [V4L2_MPEG_SS_1
] = BLACKBIRD_STREAM_MPEG1
,
735 [V4L2_MPEG_PS_2
] = BLACKBIRD_STREAM_PROGRAM
,
736 [V4L2_MPEG_TS_2
] = BLACKBIRD_STREAM_TRANSPORT
,
737 [V4L2_MPEG_PS_DVD
] = BLACKBIRD_STREAM_DVD
,
739 static enum blackbird_aspect_ratio mpeg_stream_ratios
[] = {
740 [V4L2_MPEG_ASPECT_SQUARE
] = BLACKBIRD_ASPECT_RATIO_1_1_SQUARE
,
741 [V4L2_MPEG_ASPECT_4_3
] = BLACKBIRD_ASPECT_RATIO_4_3
,
742 [V4L2_MPEG_ASPECT_16_9
] = BLACKBIRD_ASPECT_RATIO_16_9
,
743 [V4L2_MPEG_ASPECT_1_221
] = BLACKBIRD_ASPECT_RATIO_221_100
,
745 static enum blackbird_video_bitrate_type mpeg_video_bitrates
[] = {
746 [V4L2_BITRATE_NONE
] = BLACKBIRD_VIDEO_CBR
,
747 [V4L2_BITRATE_CBR
] = BLACKBIRD_VIDEO_CBR
,
748 [V4L2_BITRATE_VBR
] = BLACKBIRD_VIDEO_VBR
,
750 /* find the best layer I/II bitrate to fit a given numeric value */
751 struct bitrate_bits
{
752 u32 bits
; /* layer bits for the best fit */
753 u32 rate
; /* actual numeric value for the layer best fit */
755 struct bitrate_approximation
{
756 u32 target
; /* numeric value of the rate we want */
757 struct bitrate_bits layer
[2];
759 static struct bitrate_approximation mpeg_audio_bitrates
[] = {
760 /* target layer[0].bits layer[0].rate layer[1].bits layer[1].rate */
761 { 0, { { 0, 0, }, { 0, 0, }, }, },
762 { 32, { { BLACKBIRD_AUDIO_BITS_LAYER_1_32
, 32, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_32
, 32, }, }, },
763 { 48, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64
, 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_48
, 48, }, }, },
764 { 56, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64
, 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_56
, 56, }, }, },
765 { 64, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64
, 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_64
, 64, }, }, },
766 { 80, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96
, 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_80
, 80, }, }, },
767 { 96, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96
, 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_96
, 96, }, }, },
768 { 112, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128
, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_112
, 112, }, }, },
769 { 128, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128
, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_128
, 128, }, }, },
770 { 160, { { BLACKBIRD_AUDIO_BITS_LAYER_1_160
, 160, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_160
, 160, }, }, },
771 { 192, { { BLACKBIRD_AUDIO_BITS_LAYER_1_192
, 192, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_192
, 192, }, }, },
772 { 224, { { BLACKBIRD_AUDIO_BITS_LAYER_1_224
, 224, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_224
, 224, }, }, },
773 { 256, { { BLACKBIRD_AUDIO_BITS_LAYER_1_256
, 256, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_256
, 256, }, }, },
774 { 288, { { BLACKBIRD_AUDIO_BITS_LAYER_1_288
, 288, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320
, 320, }, }, },
775 { 320, { { BLACKBIRD_AUDIO_BITS_LAYER_1_320
, 320, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320
, 320, }, }, },
776 { 352, { { BLACKBIRD_AUDIO_BITS_LAYER_1_352
, 352, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384
, 384, }, }, },
777 { 384, { { BLACKBIRD_AUDIO_BITS_LAYER_1_384
, 384, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384
, 384, }, }, },
778 { 416, { { BLACKBIRD_AUDIO_BITS_LAYER_1_416
, 416, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384
, 384, }, }, },
779 { 448, { { BLACKBIRD_AUDIO_BITS_LAYER_1_448
, 448, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384
, 384, }, }, },
781 static const int BITRATES_SIZE
= ARRAY_SIZE(mpeg_audio_bitrates
);
783 static void blackbird_set_default_params(struct cx8802_dev
*dev
)
785 struct v4l2_mpeg_compression
*params
= &dev
->params
;
788 /* assign stream type */
789 if( params
->st_type
>= ARRAY_SIZE(mpeg_stream_types
) )
790 params
->st_type
= V4L2_MPEG_PS_2
;
791 if( params
->st_type
== V4L2_MPEG_SS_1
)
792 params
->vi_type
= V4L2_MPEG_VI_1
;
794 params
->vi_type
= V4L2_MPEG_VI_2
;
795 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_STREAM_TYPE
, 1, 0, mpeg_stream_types
[params
->st_type
]);
797 /* assign framerate */
798 if( params
->vi_frame_rate
<= 25 )
800 params
->vi_frame_rate
= 25;
801 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_FRAMERATE
, 1, 0, BLACKBIRD_FRAMERATE_PAL_25
);
805 params
->vi_frame_rate
= 30;
806 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_FRAMERATE
, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30
);
809 /* assign aspect ratio */
810 if( params
->vi_aspect_ratio
>= ARRAY_SIZE(mpeg_stream_ratios
) )
811 params
->vi_aspect_ratio
= V4L2_MPEG_ASPECT_4_3
;
812 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_ASPECT_RATIO
, 1, 0, mpeg_stream_ratios
[params
->vi_aspect_ratio
]);
814 /* assign gop properties */
815 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_GOP_STRUCTURE
, 2, 0, params
->vi_frames_per_gop
, params
->vi_bframes_count
+1);
817 /* assign gop closure */
818 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_GOP_CLOSURE
, 1, 0, params
->closed_gops
);
820 /* assign 3 2 pulldown */
821 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_3_2_PULLDOWN
, 1, 0, params
->pulldown
);
823 /* make sure the params are within bounds */
824 if( params
->st_bitrate
.mode
>= ARRAY_SIZE(mpeg_video_bitrates
) )
825 params
->vi_bitrate
.mode
= V4L2_BITRATE_NONE
;
826 if( params
->vi_bitrate
.mode
>= ARRAY_SIZE(mpeg_video_bitrates
) )
827 params
->vi_bitrate
.mode
= V4L2_BITRATE_NONE
;
828 if( params
->au_bitrate
.mode
>= ARRAY_SIZE(mpeg_video_bitrates
) )
829 params
->au_bitrate
.mode
= V4L2_BITRATE_NONE
;
831 /* assign audio properties */
832 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
833 au_params
= BLACKBIRD_AUDIO_BITS_STEREO
|
834 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
835 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE
|
836 BLACKBIRD_AUDIO_BITS_CRC_OFF
|
837 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF
|
838 BLACKBIRD_AUDIO_BITS_COPY
|
840 if( params
->au_sample_rate
<= 32000 )
842 params
->au_sample_rate
= 32000;
843 au_params
|= BLACKBIRD_AUDIO_BITS_32000HZ
;
845 else if( params
->au_sample_rate
<= 44100 )
847 params
->au_sample_rate
= 44100;
848 au_params
|= BLACKBIRD_AUDIO_BITS_44100HZ
;
852 params
->au_sample_rate
= 48000;
853 au_params
|= BLACKBIRD_AUDIO_BITS_48000HZ
;
855 if( params
->au_type
== V4L2_MPEG_AU_2_I
)
857 au_params
|= BLACKBIRD_AUDIO_BITS_LAYER_1
;
861 /* TODO: try to handle the other formats more gracefully */
862 params
->au_type
= V4L2_MPEG_AU_2_II
;
863 au_params
|= BLACKBIRD_AUDIO_BITS_LAYER_2
;
865 if( params
->au_bitrate
.mode
)
869 if( params
->au_bitrate
.mode
== V4L2_BITRATE_CBR
)
870 params
->au_bitrate
.max
= params
->vi_bitrate
.target
;
872 params
->au_bitrate
.target
= params
->vi_bitrate
.max
;
874 layer
= params
->au_type
;
875 if( params
->au_bitrate
.target
== 0 )
877 /* TODO: use the minimum possible bitrate instead of 0 ? */
880 else if( params
->au_bitrate
.target
>=
881 mpeg_audio_bitrates
[BITRATES_SIZE
-1].layer
[layer
].rate
)
883 /* clamp the bitrate to the max supported by the standard */
884 params
->au_bitrate
.target
= mpeg_audio_bitrates
[BITRATES_SIZE
-1].layer
[layer
].rate
;
885 params
->au_bitrate
.max
= params
->au_bitrate
.target
;
886 au_params
|= mpeg_audio_bitrates
[BITRATES_SIZE
-1].layer
[layer
].bits
;
890 /* round up to the nearest supported bitrate */
892 for(i
= 1; i
< BITRATES_SIZE
; i
++)
894 if( params
->au_bitrate
.target
> mpeg_audio_bitrates
[i
-1].layer
[layer
].rate
&&
895 params
->au_bitrate
.target
<= mpeg_audio_bitrates
[i
].layer
[layer
].rate
)
897 params
->au_bitrate
.target
= mpeg_audio_bitrates
[i
].layer
[layer
].rate
;
898 params
->au_bitrate
.max
= params
->au_bitrate
.target
;
899 au_params
|= mpeg_audio_bitrates
[i
].layer
[layer
].bits
;
908 params
->au_bitrate
.target
= params
->au_bitrate
.max
= 0;
911 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_AUDIO_PARAMS
, 1, 0, au_params
);
913 /* assign bitrates */
914 if( params
->vi_bitrate
.mode
)
916 /* bitrate is set, let's figure out the cbr/vbr mess */
917 if( params
->vi_bitrate
.max
< params
->vi_bitrate
.target
)
919 if( params
->vi_bitrate
.mode
== V4L2_BITRATE_CBR
)
920 params
->vi_bitrate
.max
= params
->vi_bitrate
.target
;
922 params
->vi_bitrate
.target
= params
->vi_bitrate
.max
;
927 if( params
->st_bitrate
.max
< params
->st_bitrate
.target
)
929 if( params
->st_bitrate
.mode
== V4L2_BITRATE_VBR
)
930 params
->st_bitrate
.target
= params
->st_bitrate
.max
;
932 params
->st_bitrate
.max
= params
->st_bitrate
.target
;
934 /* calculate vi_bitrate = st_bitrate - au_bitrate */
935 params
->vi_bitrate
.max
= params
->st_bitrate
.max
- params
->au_bitrate
.max
;
936 params
->vi_bitrate
.target
= params
->st_bitrate
.target
- params
->au_bitrate
.target
;
938 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_VIDEO_BITRATE
, 4, 0,
939 mpeg_video_bitrates
[params
->vi_bitrate
.mode
],
940 params
->vi_bitrate
.target
* 1000, /* kbps -> bps */
941 params
->vi_bitrate
.max
* 1000 / BLACKBIRD_PEAK_RATE_DIVISOR
, /* peak/400 */
942 BLACKBIRD_MUX_RATE_DEFAULT
/*, 0x70*/); /* encoding buffer, ckennedy */
944 /* TODO: implement the stream ID stuff:
945 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
946 ps_size, au_pesid, vi_pesid
949 #define CHECK_PARAM( name ) ( dev->params.name != params->name )
950 #define IF_PARAM( name ) if( CHECK_PARAM( name ) )
951 #define UPDATE_PARAM( name ) dev->params.name = params->name
952 void blackbird_set_params(struct cx8802_dev
*dev
, struct v4l2_mpeg_compression
*params
)
956 /* assign stream type */
957 if( params
->st_type
>= ARRAY_SIZE(mpeg_stream_types
) )
958 params
->st_type
= V4L2_MPEG_PS_2
;
959 if( params
->st_type
== V4L2_MPEG_SS_1
)
960 params
->vi_type
= V4L2_MPEG_VI_1
;
962 params
->vi_type
= V4L2_MPEG_VI_2
;
963 if( CHECK_PARAM( st_type
) || CHECK_PARAM( vi_type
) )
965 UPDATE_PARAM( st_type
);
966 UPDATE_PARAM( vi_type
);
967 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_STREAM_TYPE
, 1, 0, mpeg_stream_types
[params
->st_type
]);
970 /* assign framerate */
971 if( params
->vi_frame_rate
<= 25 )
972 params
->vi_frame_rate
= 25;
974 params
->vi_frame_rate
= 30;
975 IF_PARAM( vi_frame_rate
)
977 UPDATE_PARAM( vi_frame_rate
);
978 if( params
->vi_frame_rate
== 25 )
979 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_FRAMERATE
, 1, 0, BLACKBIRD_FRAMERATE_PAL_25
);
981 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_FRAMERATE
, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30
);
984 /* assign aspect ratio */
985 if( params
->vi_aspect_ratio
>= ARRAY_SIZE(mpeg_stream_ratios
) )
986 params
->vi_aspect_ratio
= V4L2_MPEG_ASPECT_4_3
;
987 IF_PARAM( vi_aspect_ratio
)
989 UPDATE_PARAM( vi_aspect_ratio
);
990 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_ASPECT_RATIO
, 1, 0, mpeg_stream_ratios
[params
->vi_aspect_ratio
]);
993 /* assign gop properties */
994 if( CHECK_PARAM( vi_frames_per_gop
) || CHECK_PARAM( vi_bframes_count
) )
996 UPDATE_PARAM( vi_frames_per_gop
);
997 UPDATE_PARAM( vi_bframes_count
);
998 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_GOP_STRUCTURE
, 2, 0, params
->vi_frames_per_gop
, params
->vi_bframes_count
+1);
1001 /* assign gop closure */
1002 IF_PARAM( closed_gops
)
1004 UPDATE_PARAM( closed_gops
);
1005 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_GOP_CLOSURE
, 1, 0, params
->closed_gops
);
1008 /* assign 3 2 pulldown */
1009 IF_PARAM( pulldown
)
1011 UPDATE_PARAM( pulldown
);
1012 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_3_2_PULLDOWN
, 1, 0, params
->pulldown
);
1015 /* make sure the params are within bounds */
1016 if( params
->st_bitrate
.mode
>= ARRAY_SIZE(mpeg_video_bitrates
) )
1017 params
->vi_bitrate
.mode
= V4L2_BITRATE_NONE
;
1018 if( params
->vi_bitrate
.mode
>= ARRAY_SIZE(mpeg_video_bitrates
) )
1019 params
->vi_bitrate
.mode
= V4L2_BITRATE_NONE
;
1020 if( params
->au_bitrate
.mode
>= ARRAY_SIZE(mpeg_video_bitrates
) )
1021 params
->au_bitrate
.mode
= V4L2_BITRATE_NONE
;
1023 /* assign audio properties */
1024 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
1025 au_params
= BLACKBIRD_AUDIO_BITS_STEREO
|
1026 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
1027 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE
|
1028 BLACKBIRD_AUDIO_BITS_CRC_OFF
|
1029 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF
|
1030 BLACKBIRD_AUDIO_BITS_COPY
|
1032 if( params
->au_sample_rate
< 32000 )
1034 params
->au_sample_rate
= 32000;
1035 au_params
|= BLACKBIRD_AUDIO_BITS_32000HZ
;
1037 else if( params
->au_sample_rate
< 44100 )
1039 params
->au_sample_rate
= 44100;
1040 au_params
|= BLACKBIRD_AUDIO_BITS_44100HZ
;
1044 params
->au_sample_rate
= 48000;
1045 au_params
|= BLACKBIRD_AUDIO_BITS_48000HZ
;
1047 if( params
->au_type
== V4L2_MPEG_AU_2_I
)
1049 au_params
|= BLACKBIRD_AUDIO_BITS_LAYER_1
;
1053 /* TODO: try to handle the other formats more gracefully */
1054 params
->au_type
= V4L2_MPEG_AU_2_II
;
1055 au_params
|= BLACKBIRD_AUDIO_BITS_LAYER_2
;
1057 if( params
->au_bitrate
.mode
)
1061 if( params
->au_bitrate
.mode
== V4L2_BITRATE_CBR
)
1062 params
->au_bitrate
.max
= params
->vi_bitrate
.target
;
1064 params
->au_bitrate
.target
= params
->vi_bitrate
.max
;
1066 layer
= params
->au_type
;
1067 if( params
->au_bitrate
.target
== 0 )
1069 /* TODO: use the minimum possible bitrate instead of 0 ? */
1072 else if( params
->au_bitrate
.target
>=
1073 mpeg_audio_bitrates
[BITRATES_SIZE
-1].layer
[layer
].rate
)
1075 /* clamp the bitrate to the max supported by the standard */
1076 params
->au_bitrate
.target
= mpeg_audio_bitrates
[BITRATES_SIZE
-1].layer
[layer
].rate
;
1077 params
->au_bitrate
.max
= params
->au_bitrate
.target
;
1078 au_params
|= mpeg_audio_bitrates
[BITRATES_SIZE
-1].layer
[layer
].bits
;
1082 /* round up to the nearest supported bitrate */
1084 for(i
= 1; i
< BITRATES_SIZE
; i
++)
1086 if( params
->au_bitrate
.target
> mpeg_audio_bitrates
[i
-1].layer
[layer
].rate
&&
1087 params
->au_bitrate
.target
<= mpeg_audio_bitrates
[i
].layer
[layer
].rate
)
1089 params
->au_bitrate
.target
= mpeg_audio_bitrates
[i
].layer
[layer
].rate
;
1090 params
->au_bitrate
.max
= params
->au_bitrate
.target
;
1091 au_params
|= mpeg_audio_bitrates
[i
].layer
[layer
].bits
;
1100 params
->au_bitrate
.target
= params
->au_bitrate
.max
= 0;
1103 if( CHECK_PARAM( au_type
) || CHECK_PARAM( au_sample_rate
)
1104 || CHECK_PARAM( au_bitrate
.mode
) || CHECK_PARAM( au_bitrate
.max
)
1105 || CHECK_PARAM( au_bitrate
.target
)
1108 UPDATE_PARAM( au_type
);
1109 UPDATE_PARAM( au_sample_rate
);
1110 UPDATE_PARAM( au_bitrate
);
1111 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_AUDIO_PARAMS
, 1, 0, au_params
);
1114 /* assign bitrates */
1115 if( params
->vi_bitrate
.mode
)
1117 /* bitrate is set, let's figure out the cbr/vbr mess */
1118 if( params
->vi_bitrate
.max
< params
->vi_bitrate
.target
)
1120 if( params
->vi_bitrate
.mode
== V4L2_BITRATE_CBR
)
1121 params
->vi_bitrate
.max
= params
->vi_bitrate
.target
;
1123 params
->vi_bitrate
.target
= params
->vi_bitrate
.max
;
1128 if( params
->st_bitrate
.max
< params
->st_bitrate
.target
)
1130 if( params
->st_bitrate
.mode
== V4L2_BITRATE_VBR
)
1131 params
->st_bitrate
.target
= params
->st_bitrate
.max
;
1133 params
->st_bitrate
.max
= params
->st_bitrate
.target
;
1135 /* calculate vi_bitrate = st_bitrate - au_bitrate */
1136 params
->vi_bitrate
.max
= params
->st_bitrate
.max
- params
->au_bitrate
.max
;
1137 params
->vi_bitrate
.target
= params
->st_bitrate
.target
- params
->au_bitrate
.target
;
1139 UPDATE_PARAM( st_bitrate
);
1140 if( CHECK_PARAM( vi_bitrate
.mode
) || CHECK_PARAM( vi_bitrate
.max
)
1141 || CHECK_PARAM( vi_bitrate
.target
)
1144 UPDATE_PARAM( vi_bitrate
);
1145 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_VIDEO_BITRATE
, 4, 0,
1146 mpeg_video_bitrates
[params
->vi_bitrate
.mode
],
1147 params
->vi_bitrate
.target
* 1000, /* kbps -> bps */
1148 params
->vi_bitrate
.max
* 1000 / BLACKBIRD_PEAK_RATE_DIVISOR
, /* peak/400 */
1149 BLACKBIRD_MUX_RATE_DEFAULT
/*, 0x70*/); /* encoding buffer, ckennedy */
1152 /* TODO: implement the stream ID stuff:
1153 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
1154 ps_size, au_pesid, vi_pesid
1156 UPDATE_PARAM( ts_pid_pmt
);
1157 UPDATE_PARAM( ts_pid_audio
);
1158 UPDATE_PARAM( ts_pid_video
);
1159 UPDATE_PARAM( ts_pid_pcr
);
1160 UPDATE_PARAM( ps_size
);
1161 UPDATE_PARAM( au_pesid
);
1162 UPDATE_PARAM( vi_pesid
);
1165 static void blackbird_set_default_dnr_params(struct cx8802_dev
*dev
)
1167 /* assign dnr filter mode */
1168 if( dev
->dnr_params
.mode
> BLACKBIRD_DNR_BITS_AUTO
)
1169 dev
->dnr_params
.mode
= BLACKBIRD_DNR_BITS_MANUAL
;
1170 if( dev
->dnr_params
.type
> BLACKBIRD_MEDIAN_FILTER_DIAGONAL
)
1171 dev
->dnr_params
.type
= BLACKBIRD_MEDIAN_FILTER_DISABLED
;
1172 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_DNR_MODE
, 2, 0,
1173 dev
->dnr_params
.mode
,
1174 dev
->dnr_params
.type
1177 /* assign dnr filter props*/
1178 if( dev
->dnr_params
.spatial
> 15 )
1179 dev
->dnr_params
.spatial
= 15;
1180 if( dev
->dnr_params
.temporal
> 31 )
1181 dev
->dnr_params
.temporal
= 31;
1182 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_MANUAL_DNR
, 2, 0,
1183 dev
->dnr_params
.spatial
,
1184 dev
->dnr_params
.temporal
1187 #define CHECK_DNR_PARAM( name ) ( dev->dnr_params.name != dnr_params->name )
1188 #define UPDATE_DNR_PARAM( name ) dev->dnr_params.name = dnr_params->name
1189 void blackbird_set_dnr_params(struct cx8802_dev
*dev
, struct blackbird_dnr
* dnr_params
)
1191 /* assign dnr filter mode */
1193 if( dnr_params
->mode
> BLACKBIRD_DNR_BITS_AUTO
)
1194 dnr_params
->mode
= BLACKBIRD_DNR_BITS_MANUAL
;
1195 if( dnr_params
->type
> BLACKBIRD_MEDIAN_FILTER_DIAGONAL
)
1196 dnr_params
->type
= BLACKBIRD_MEDIAN_FILTER_DISABLED
;
1197 /* check if the params actually changed */
1198 if( CHECK_DNR_PARAM( mode
) || CHECK_DNR_PARAM( type
) )
1200 UPDATE_DNR_PARAM( mode
);
1201 UPDATE_DNR_PARAM( type
);
1202 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_DNR_MODE
, 2, 0, dnr_params
->mode
, dnr_params
->type
);
1205 /* assign dnr filter props*/
1206 if( dnr_params
->spatial
> 15 )
1207 dnr_params
->spatial
= 15;
1208 if( dnr_params
->temporal
> 31 )
1209 dnr_params
->temporal
= 31;
1210 if( CHECK_DNR_PARAM( spatial
) || CHECK_DNR_PARAM( temporal
) )
1212 UPDATE_DNR_PARAM( spatial
);
1213 UPDATE_DNR_PARAM( temporal
);
1214 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_MANUAL_DNR
, 2, 0, dnr_params
->spatial
, dnr_params
->temporal
);
1218 static void blackbird_codec_settings(struct cx8802_dev
*dev
)
1221 /* assign output port */
1222 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_OUTPUT_PORT
, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING
); /* Host */
1224 /* assign frame size */
1225 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_RESOLUTION
, 2, 0,
1226 dev
->height
, dev
->width
);
1228 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
1229 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_DNR_MEDIAN
, 4, 0, 0, 255, 0, 255);
1231 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */
1232 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_SPATIAL_FILTER
, 2, 0,
1233 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ
,
1234 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
1237 /* assign frame drop rate */
1238 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */
1240 blackbird_set_default_params(dev
);
1241 blackbird_set_default_dnr_params(dev
);
1244 static int blackbird_initialize_codec(struct cx8802_dev
*dev
)
1246 struct cx88_core
*core
= dev
->core
;
1250 dprintk(1,"Initialize codec\n");
1251 retval
= blackbird_api_cmd(dev
, BLACKBIRD_API_PING
, 0, 0); /* ping */
1253 /* ping was not successful, reset and upload firmware */
1254 cx_write(MO_SRST_IO
, 0); /* SYS_RSTO=0 */
1256 cx_write(MO_SRST_IO
, 1); /* SYS_RSTO=1 */
1258 retval
= blackbird_load_firmware(dev
);
1262 dev
->mailbox
= blackbird_find_mailbox(dev
);
1263 if (dev
->mailbox
< 0)
1266 retval
= blackbird_api_cmd(dev
, BLACKBIRD_API_PING
, 0, 0); /* ping */
1268 dprintk(0, "ERROR: Firmware ping failed!\n");
1272 retval
= blackbird_api_cmd(dev
, BLACKBIRD_API_GET_VERSION
, 0, 1, &version
);
1274 dprintk(0, "ERROR: Firmware get encoder version failed!\n");
1277 dprintk(0, "Firmware version is 0x%08x\n", version
);
1281 cx_write(MO_PINMUX_IO
, 0x88); /* 656-8bit IO and enable MPEG parallel IO */
1282 cx_clear(MO_INPUT_FORMAT
, 0x100); /* chroma subcarrier lock to normal? */
1283 cx_write(MO_VBOS_CONTROL
, 0x84A00); /* no 656 mode, 8-bit pixels, disable VBI */
1284 cx_clear(MO_OUTPUT_FORMAT
, 0x0008); /* Normal Y-limits to let the mpeg encoder sync */
1286 blackbird_codec_settings(dev
);
1289 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
1290 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
1291 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */
1292 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_CAPTURE_LINES
, 2, 0,
1293 BLACKBIRD_FIELD1_SAA7115
,
1294 BLACKBIRD_FIELD1_SAA7115
1297 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */
1298 blackbird_api_cmd(dev
, BLACKBIRD_API_SET_CUSTOM_DATA
, 12, 0,
1299 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA
,
1300 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1302 /* initialize the video input */
1303 blackbird_api_cmd(dev
, BLACKBIRD_API_INIT_VIDEO_INPUT
, 0, 0);
1307 blackbird_api_cmd(dev
, BLACKBIRD_API_MUTE_VIDEO
, 1, 0, BLACKBIRD_UNMUTE
);
1309 blackbird_api_cmd(dev
, BLACKBIRD_API_MUTE_AUDIO
, 1, 0, BLACKBIRD_UNMUTE
);
1312 /* start capturing to the host interface */
1313 /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); */
1314 blackbird_api_cmd(dev
, BLACKBIRD_API_BEGIN_CAPTURE
, 2, 0,
1315 BLACKBIRD_MPEG_CAPTURE
,
1316 BLACKBIRD_RAW_BITS_NONE
1320 blackbird_api_cmd(dev
, BLACKBIRD_API_REFRESH_INPUT
, 0,0);
1324 /* ------------------------------------------------------------------ */
1326 static int bb_buf_setup(struct videobuf_queue
*q
,
1327 unsigned int *count
, unsigned int *size
)
1329 struct cx8802_fh
*fh
= q
->priv_data
;
1331 fh
->dev
->ts_packet_size
= 188 * 4; /* was: 512 */
1332 fh
->dev
->ts_packet_count
= mpegbufs
; /* was: 100 */
1334 *size
= fh
->dev
->ts_packet_size
* fh
->dev
->ts_packet_count
;
1335 *count
= fh
->dev
->ts_packet_count
;
1340 bb_buf_prepare(struct videobuf_queue
*q
, struct videobuf_buffer
*vb
,
1341 enum v4l2_field field
)
1343 struct cx8802_fh
*fh
= q
->priv_data
;
1344 return cx8802_buf_prepare(fh
->dev
, (struct cx88_buffer
*)vb
, field
);
1348 bb_buf_queue(struct videobuf_queue
*q
, struct videobuf_buffer
*vb
)
1350 struct cx8802_fh
*fh
= q
->priv_data
;
1351 cx8802_buf_queue(fh
->dev
, (struct cx88_buffer
*)vb
);
1355 bb_buf_release(struct videobuf_queue
*q
, struct videobuf_buffer
*vb
)
1357 struct cx8802_fh
*fh
= q
->priv_data
;
1358 cx88_free_buffer(fh
->dev
->pci
, (struct cx88_buffer
*)vb
);
1361 static struct videobuf_queue_ops blackbird_qops
= {
1362 .buf_setup
= bb_buf_setup
,
1363 .buf_prepare
= bb_buf_prepare
,
1364 .buf_queue
= bb_buf_queue
,
1365 .buf_release
= bb_buf_release
,
1368 /* ------------------------------------------------------------------ */
1370 static int mpeg_do_ioctl(struct inode
*inode
, struct file
*file
,
1371 unsigned int cmd
, void *arg
)
1373 struct cx8802_fh
*fh
= file
->private_data
;
1374 struct cx8802_dev
*dev
= fh
->dev
;
1375 struct cx88_core
*core
= dev
->core
;
1378 cx88_print_ioctl(core
->name
,cmd
);
1382 /* --- capabilities ------------------------------------------ */
1383 case VIDIOC_QUERYCAP
:
1385 struct v4l2_capability
*cap
= arg
;
1387 memset(cap
,0,sizeof(*cap
));
1388 strcpy(cap
->driver
, "cx88_blackbird");
1389 strlcpy(cap
->card
, cx88_boards
[core
->board
].name
,sizeof(cap
->card
));
1390 sprintf(cap
->bus_info
,"PCI:%s",pci_name(dev
->pci
));
1391 cap
->version
= CX88_VERSION_CODE
;
1393 V4L2_CAP_VIDEO_CAPTURE
|
1394 V4L2_CAP_READWRITE
|
1395 V4L2_CAP_STREAMING
|
1397 if (UNSET
!= core
->tuner_type
)
1398 cap
->capabilities
|= V4L2_CAP_TUNER
;
1403 /* --- capture ioctls ---------------------------------------- */
1404 case VIDIOC_ENUM_FMT
:
1406 struct v4l2_fmtdesc
*f
= arg
;
1413 memset(f
,0,sizeof(*f
));
1415 strlcpy(f
->description
, "MPEG", sizeof(f
->description
));
1416 f
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1417 f
->pixelformat
= V4L2_PIX_FMT_MPEG
;
1422 struct v4l2_format
*f
= arg
;
1424 memset(f
,0,sizeof(*f
));
1425 f
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1426 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_MPEG
;
1427 f
->fmt
.pix
.bytesperline
= 0;
1428 f
->fmt
.pix
.sizeimage
= dev
->ts_packet_size
* dev
->ts_packet_count
; /* 188 * 4 * 1024; */
1429 f
->fmt
.pix
.colorspace
= 0;
1430 f
->fmt
.pix
.width
= dev
->width
;
1431 f
->fmt
.pix
.height
= dev
->height
;
1432 f
->fmt
.pix
.field
= fh
->mpegq
.field
;
1433 dprintk(0,"VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
1434 dev
->width
, dev
->height
, fh
->mpegq
.field
);
1437 case VIDIOC_TRY_FMT
:
1439 struct v4l2_format
*f
= arg
;
1441 f
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1442 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_MPEG
;
1443 f
->fmt
.pix
.bytesperline
= 0;
1444 f
->fmt
.pix
.sizeimage
= dev
->ts_packet_size
* dev
->ts_packet_count
; /* 188 * 4 * 1024; */;
1445 f
->fmt
.pix
.colorspace
= 0;
1446 dprintk(0,"VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
1447 dev
->width
, dev
->height
, fh
->mpegq
.field
);
1452 struct v4l2_format
*f
= arg
;
1454 f
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1455 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_MPEG
;
1456 f
->fmt
.pix
.bytesperline
= 0;
1457 f
->fmt
.pix
.sizeimage
= dev
->ts_packet_size
* dev
->ts_packet_count
; /* 188 * 4 * 1024; */;
1458 f
->fmt
.pix
.colorspace
= 0;
1459 dprintk(0,"VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
1460 f
->fmt
.pix
.width
, f
->fmt
.pix
.height
, f
->fmt
.pix
.field
);
1464 /* --- streaming capture ------------------------------------- */
1465 case VIDIOC_REQBUFS
:
1466 return videobuf_reqbufs(&fh
->mpegq
, arg
);
1468 case VIDIOC_QUERYBUF
:
1469 return videobuf_querybuf(&fh
->mpegq
, arg
);
1472 return videobuf_qbuf(&fh
->mpegq
, arg
);
1475 return videobuf_dqbuf(&fh
->mpegq
, arg
,
1476 file
->f_flags
& O_NONBLOCK
);
1478 case VIDIOC_STREAMON
:
1479 return videobuf_streamon(&fh
->mpegq
);
1481 case VIDIOC_STREAMOFF
:
1482 return videobuf_streamoff(&fh
->mpegq
);
1484 /* --- mpeg compression -------------------------------------- */
1485 case VIDIOC_G_MPEGCOMP
:
1487 struct v4l2_mpeg_compression
*f
= arg
;
1489 memcpy(f
,&dev
->params
,sizeof(*f
));
1492 case VIDIOC_S_MPEGCOMP
:
1494 struct v4l2_mpeg_compression
*f
= arg
;
1496 blackbird_set_params(dev
, f
);
1501 return cx88_do_ioctl( inode
, file
, 0, dev
->core
, cmd
, arg
, cx88_ioctl_hook
);
1506 int (*cx88_ioctl_hook
)(struct inode
*inode
, struct file
*file
,
1507 unsigned int cmd
, void *arg
);
1508 unsigned int (*cx88_ioctl_translator
)(unsigned int cmd
);
1510 static unsigned int mpeg_translate_ioctl(unsigned int cmd
)
1515 static int mpeg_ioctl(struct inode
*inode
, struct file
*file
,
1516 unsigned int cmd
, unsigned long arg
)
1518 cmd
= cx88_ioctl_translator( cmd
);
1519 return video_usercopy(inode
, file
, cmd
, arg
, cx88_ioctl_hook
);
1522 static int mpeg_open(struct inode
*inode
, struct file
*file
)
1524 int minor
= iminor(inode
);
1525 struct cx8802_dev
*h
,*dev
= NULL
;
1526 struct cx8802_fh
*fh
;
1527 struct list_head
*list
;
1529 list_for_each(list
,&cx8802_devlist
) {
1530 h
= list_entry(list
, struct cx8802_dev
, devlist
);
1531 if (h
->mpeg_dev
->minor
== minor
)
1537 if (blackbird_initialize_codec(dev
) < 0)
1539 dprintk(1,"open minor=%d\n",minor
);
1541 /* allocate + initialize per filehandle data */
1542 fh
= kmalloc(sizeof(*fh
),GFP_KERNEL
);
1545 memset(fh
,0,sizeof(*fh
));
1546 file
->private_data
= fh
;
1549 videobuf_queue_init(&fh
->mpegq
, &blackbird_qops
,
1550 dev
->pci
, &dev
->slock
,
1551 V4L2_BUF_TYPE_VIDEO_CAPTURE
,
1552 V4L2_FIELD_INTERLACED
,
1553 sizeof(struct cx88_buffer
),
1556 /* FIXME: locking against other video device */
1557 cx88_set_scale(dev
->core
, dev
->width
, dev
->height
,
1563 static int mpeg_release(struct inode
*inode
, struct file
*file
)
1565 struct cx8802_fh
*fh
= file
->private_data
;
1567 /* blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */
1568 blackbird_api_cmd(fh
->dev
, BLACKBIRD_API_END_CAPTURE
, 3, 0,
1570 BLACKBIRD_MPEG_CAPTURE
,
1571 BLACKBIRD_RAW_BITS_NONE
1574 /* stop mpeg capture */
1575 if (fh
->mpegq
.streaming
)
1576 videobuf_streamoff(&fh
->mpegq
);
1577 if (fh
->mpegq
.reading
)
1578 videobuf_read_stop(&fh
->mpegq
);
1580 videobuf_mmap_free(&fh
->mpegq
);
1581 file
->private_data
= NULL
;
1587 mpeg_read(struct file
*file
, char __user
*data
, size_t count
, loff_t
*ppos
)
1589 struct cx8802_fh
*fh
= file
->private_data
;
1591 return videobuf_read_stream(&fh
->mpegq
, data
, count
, ppos
, 0,
1592 file
->f_flags
& O_NONBLOCK
);
1596 mpeg_poll(struct file
*file
, struct poll_table_struct
*wait
)
1598 struct cx8802_fh
*fh
= file
->private_data
;
1600 return videobuf_poll_stream(file
, &fh
->mpegq
, wait
);
1604 mpeg_mmap(struct file
*file
, struct vm_area_struct
* vma
)
1606 struct cx8802_fh
*fh
= file
->private_data
;
1608 return videobuf_mmap_mapper(&fh
->mpegq
, vma
);
1611 static struct file_operations mpeg_fops
=
1613 .owner
= THIS_MODULE
,
1615 .release
= mpeg_release
,
1619 .ioctl
= mpeg_ioctl
,
1620 .llseek
= no_llseek
,
1623 static struct video_device cx8802_mpeg_template
=
1626 .type
= VID_TYPE_CAPTURE
|VID_TYPE_TUNER
|VID_TYPE_SCALES
|VID_TYPE_MPEG_ENCODER
,
1632 /* ------------------------------------------------------------------ */
1634 static void blackbird_unregister_video(struct cx8802_dev
*dev
)
1636 if (dev
->mpeg_dev
) {
1637 if (-1 != dev
->mpeg_dev
->minor
)
1638 video_unregister_device(dev
->mpeg_dev
);
1640 video_device_release(dev
->mpeg_dev
);
1641 dev
->mpeg_dev
= NULL
;
1645 static int blackbird_register_video(struct cx8802_dev
*dev
)
1649 dev
->mpeg_dev
= cx88_vdev_init(dev
->core
,dev
->pci
,
1650 &cx8802_mpeg_template
,"mpeg");
1651 err
= video_register_device(dev
->mpeg_dev
,VFL_TYPE_GRABBER
, -1);
1653 printk(KERN_INFO
"%s/2: can't register mpeg device\n",
1657 printk(KERN_INFO
"%s/2: registered device video%d [mpeg]\n",
1658 dev
->core
->name
,dev
->mpeg_dev
->minor
& 0x1f);
1662 /* ----------------------------------------------------------- */
1664 static int __devinit
blackbird_probe(struct pci_dev
*pci_dev
,
1665 const struct pci_device_id
*pci_id
)
1667 struct cx8802_dev
*dev
;
1668 struct cx88_core
*core
;
1672 core
= cx88_core_get(pci_dev
);
1677 if (!cx88_boards
[core
->board
].blackbird
)
1681 dev
= kmalloc(sizeof(*dev
),GFP_KERNEL
);
1684 memset(dev
,0,sizeof(*dev
));
1689 memcpy(&dev
->params
,&default_mpeg_params
,sizeof(default_mpeg_params
));
1690 memcpy(&dev
->dnr_params
,&default_dnr_params
,sizeof(default_dnr_params
));
1692 err
= cx8802_init_common(dev
);
1696 /* blackbird stuff */
1697 printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n",
1699 host_setup(dev
->core
);
1701 list_add_tail(&dev
->devlist
,&cx8802_devlist
);
1702 blackbird_register_video(dev
);
1704 /* initial device configuration: needed ? */
1711 cx88_core_put(core
,pci_dev
);
1715 static void __devexit
blackbird_remove(struct pci_dev
*pci_dev
)
1717 struct cx8802_dev
*dev
= pci_get_drvdata(pci_dev
);
1720 blackbird_unregister_video(dev
);
1721 list_del(&dev
->devlist
);
1724 cx8802_fini_common(dev
);
1725 cx88_core_put(dev
->core
,dev
->pci
);
1729 static struct pci_device_id cx8802_pci_tbl
[] = {
1733 .subvendor
= PCI_ANY_ID
,
1734 .subdevice
= PCI_ANY_ID
,
1736 /* --- end of list --- */
1739 MODULE_DEVICE_TABLE(pci
, cx8802_pci_tbl
);
1741 static struct pci_driver blackbird_pci_driver
= {
1742 .name
= "cx88-blackbird",
1743 .id_table
= cx8802_pci_tbl
,
1744 .probe
= blackbird_probe
,
1745 .remove
= __devexit_p(blackbird_remove
),
1746 .suspend
= cx8802_suspend_common
,
1747 .resume
= cx8802_resume_common
,
1750 static int blackbird_init(void)
1752 printk(KERN_INFO
"cx2388x blackbird driver version %d.%d.%d loaded\n",
1753 (CX88_VERSION_CODE
>> 16) & 0xff,
1754 (CX88_VERSION_CODE
>> 8) & 0xff,
1755 CX88_VERSION_CODE
& 0xff);
1757 printk(KERN_INFO
"cx2388x: snapshot date %04d-%02d-%02d\n",
1758 SNAPSHOT
/10000, (SNAPSHOT
/100)%100, SNAPSHOT
%100);
1760 cx88_ioctl_hook
= mpeg_do_ioctl
;
1761 cx88_ioctl_translator
= mpeg_translate_ioctl
;
1762 return pci_register_driver(&blackbird_pci_driver
);
1765 static void blackbird_fini(void)
1767 pci_unregister_driver(&blackbird_pci_driver
);
1770 module_init(blackbird_init
);
1771 module_exit(blackbird_fini
);
1773 EXPORT_SYMBOL(cx88_ioctl_hook
);
1774 EXPORT_SYMBOL(cx88_ioctl_translator
);
1775 EXPORT_SYMBOL(blackbird_set_params
);
1776 EXPORT_SYMBOL(blackbird_set_dnr_params
);
1778 /* ----------------------------------------------------------- */
1783 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off