diff options
author | Mike Isely <isely@pobox.com> | 2006-06-25 19:05:01 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-06-26 23:17:32 -0400 |
commit | b30d244176846de3480ae17097a5f7831ec6aaf6 (patch) | |
tree | fba5650757a84032802b87635b7fe41d77c8e3cd /drivers | |
parent | 1d9f8461f1a870571f9403a312c26deec3305be5 (diff) |
V4L/DVB (4244): Implement use of cx2341x module in pvrusb2 driver
Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | 7 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-encoder.c | 228 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | 16 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 330 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.h | 11 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-video-v4l.c | 7 |
6 files changed, 304 insertions, 295 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c index 47e7f5dbd516..27eadaff75a0 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | |||
@@ -104,12 +104,15 @@ static void set_audio(struct pvr2_v4l_cx2584x *ctxt) | |||
104 | hdw->srate_val); | 104 | hdw->srate_val); |
105 | switch (hdw->srate_val) { | 105 | switch (hdw->srate_val) { |
106 | default: | 106 | default: |
107 | case PVR2_CVAL_SRATE_48: | 107 | case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: |
108 | val = 48000; | 108 | val = 48000; |
109 | break; | 109 | break; |
110 | case PVR2_CVAL_SRATE_44_1: | 110 | case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: |
111 | val = 44100; | 111 | val = 44100; |
112 | break; | 112 | break; |
113 | case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: | ||
114 | val = 32000; | ||
115 | break; | ||
113 | } | 116 | } |
114 | pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); | 117 | pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); |
115 | } | 118 | } |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 47c8e0203ce7..d944081072e6 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c | |||
@@ -27,34 +27,6 @@ | |||
27 | #include "pvrusb2-hdw-internal.h" | 27 | #include "pvrusb2-hdw-internal.h" |
28 | #include "pvrusb2-debug.h" | 28 | #include "pvrusb2-debug.h" |
29 | 29 | ||
30 | static u32 pvr_tbl_emphasis [] = { | ||
31 | [PVR2_CVAL_AUDIOEMPHASIS_NONE] = 0x0 << 12, | ||
32 | [PVR2_CVAL_AUDIOEMPHASIS_50_15] = 0x1 << 12, | ||
33 | [PVR2_CVAL_AUDIOEMPHASIS_CCITT] = 0x3 << 12, | ||
34 | }; | ||
35 | |||
36 | static u32 pvr_tbl_srate[] = { | ||
37 | [PVR2_CVAL_SRATE_48] = 0x01, | ||
38 | [PVR2_CVAL_SRATE_44_1] = 0x00, | ||
39 | }; | ||
40 | |||
41 | static u32 pvr_tbl_audiobitrate[] = { | ||
42 | [PVR2_CVAL_AUDIOBITRATE_384] = 0xe << 4, | ||
43 | [PVR2_CVAL_AUDIOBITRATE_320] = 0xd << 4, | ||
44 | [PVR2_CVAL_AUDIOBITRATE_256] = 0xc << 4, | ||
45 | [PVR2_CVAL_AUDIOBITRATE_224] = 0xb << 4, | ||
46 | [PVR2_CVAL_AUDIOBITRATE_192] = 0xa << 4, | ||
47 | [PVR2_CVAL_AUDIOBITRATE_160] = 0x9 << 4, | ||
48 | [PVR2_CVAL_AUDIOBITRATE_128] = 0x8 << 4, | ||
49 | [PVR2_CVAL_AUDIOBITRATE_112] = 0x7 << 4, | ||
50 | [PVR2_CVAL_AUDIOBITRATE_96] = 0x6 << 4, | ||
51 | [PVR2_CVAL_AUDIOBITRATE_80] = 0x5 << 4, | ||
52 | [PVR2_CVAL_AUDIOBITRATE_64] = 0x4 << 4, | ||
53 | [PVR2_CVAL_AUDIOBITRATE_56] = 0x3 << 4, | ||
54 | [PVR2_CVAL_AUDIOBITRATE_48] = 0x2 << 4, | ||
55 | [PVR2_CVAL_AUDIOBITRATE_32] = 0x1 << 4, | ||
56 | [PVR2_CVAL_AUDIOBITRATE_VBR] = 0x0 << 4, | ||
57 | }; | ||
58 | 30 | ||
59 | 31 | ||
60 | /* Firmware mailbox flags - definitions found from ivtv */ | 32 | /* Firmware mailbox flags - definitions found from ivtv */ |
@@ -316,171 +288,67 @@ static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd, | |||
316 | return pvr2_encoder_cmd(hdw,cmd,args,0,data); | 288 | return pvr2_encoder_cmd(hdw,cmd,args,0,data); |
317 | } | 289 | } |
318 | 290 | ||
319 | |||
320 | int pvr2_encoder_configure(struct pvr2_hdw *hdw) | 291 | int pvr2_encoder_configure(struct pvr2_hdw *hdw) |
321 | { | 292 | { |
322 | int ret = 0, audio, i; | 293 | int ret; |
323 | v4l2_std_id vd_std = hdw->std_mask_cur; | 294 | pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure" |
324 | int height = hdw->res_ver_val; | 295 | " (cx2341x module)"); |
325 | int width = hdw->res_hor_val; | 296 | hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING; |
326 | int height_full = !hdw->interlace_val; | 297 | hdw->enc_ctl_state.width = hdw->res_hor_val; |
327 | 298 | hdw->enc_ctl_state.height = hdw->res_ver_val; | |
328 | int is_30fps, is_ntsc; | 299 | hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & |
329 | 300 | (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ? | |
330 | if (vd_std & V4L2_STD_NTSC) { | 301 | 0 : 1); |
331 | is_ntsc=1; | ||
332 | is_30fps=1; | ||
333 | } else if (vd_std & V4L2_STD_PAL_M) { | ||
334 | is_ntsc=0; | ||
335 | is_30fps=1; | ||
336 | } else { | ||
337 | is_ntsc=0; | ||
338 | is_30fps=0; | ||
339 | } | ||
340 | 302 | ||
341 | pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure (native)"); | 303 | ret = 0; |
342 | 304 | ||
343 | /* set stream output port. Some notes here: The ivtv-derived | 305 | if (!ret) ret = pvr2_encoder_vcmd( |
344 | encoder documentation says that this command only gets a | 306 | hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, |
345 | single argument. However the Windows driver for the model | 307 | 0xf0, 0xf0); |
346 | 29xxx series hardware has been sending 0x01 as a second | ||
347 | argument, while the Windows driver for the model 24xxx | ||
348 | series hardware has been sending 0x02 as a second argument. | ||
349 | Confusing matters further are the observations that 0x01 | ||
350 | for that second argument simply won't work on the 24xxx | ||
351 | hardware, while 0x02 will work on the 29xxx - except that | ||
352 | when we use 0x02 then xawtv breaks due to a loss of | ||
353 | synchronization with the mpeg packet headers. While xawtv | ||
354 | should be fixed to let it resync better (I did try to | ||
355 | contact Gerd about this but he has not answered), it has | ||
356 | also been determined that sending 0x00 as this mystery | ||
357 | second argument seems to work on both hardware models AND | ||
358 | xawtv works again. So we're going to send 0x00. */ | ||
359 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_OUTPUT_PORT, 2, | ||
360 | 0x01, 0x00); | ||
361 | |||
362 | /* set the Program Index Information. We want I,P,B frames (max 400) */ | ||
363 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_PGM_INDEX_INFO, 2, | ||
364 | 0x07, 0x0190); | ||
365 | |||
366 | /* NOTE : windows driver sends these */ | ||
367 | /* Mike Isely <isely@pobox.com> 7-Mar-2006 The windows driver | ||
368 | sends the following commands but if we do the same then | ||
369 | many apps are no longer able to read the video stream. | ||
370 | Leaving these out seems to do no harm at all, so they're | ||
371 | commented out for that reason. */ | ||
372 | #ifdef notdef | ||
373 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 5,0,0,0); | ||
374 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 3,1,0,0); | ||
375 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0); | ||
376 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 4,1,0,0); | ||
377 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0); | ||
378 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0); | ||
379 | #endif | ||
380 | |||
381 | /* Strange compared to ivtv data. */ | ||
382 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, | ||
383 | 0xf0, 0xf0); | ||
384 | 308 | ||
385 | /* setup firmware to notify us about some events (don't know why...) */ | 309 | /* setup firmware to notify us about some events (don't know why...) */ |
386 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, | 310 | if (!ret) ret = pvr2_encoder_vcmd( |
387 | 0, 0, 0x10000000, 0xffffffff); | 311 | hdw,CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, |
312 | 0, 0, 0x10000000, 0xffffffff); | ||
313 | |||
314 | if (!ret) ret = pvr2_encoder_vcmd( | ||
315 | hdw,CX2341X_ENC_SET_VBI_LINE, 5, | ||
316 | 0xffffffff,0,0,0,0); | ||
317 | |||
318 | if (ret) { | ||
319 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
320 | "Failed to configure cx32416"); | ||
321 | return ret; | ||
322 | } | ||
388 | 323 | ||
389 | /* set fps to 25 or 30 (1 or 0)*/ | 324 | ret = cx2341x_update(hdw,pvr2_encoder_cmd, |
390 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_FRAME_RATE, 1, | 325 | (hdw->enc_cur_valid ? &hdw->enc_cur_state : 0), |
391 | is_30fps ? 0 : 1); | 326 | &hdw->enc_ctl_state); |
327 | if (ret) { | ||
328 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
329 | "Error from cx2341x module code=%d",ret); | ||
330 | return ret; | ||
331 | } | ||
392 | 332 | ||
393 | /* set encoding resolution */ | 333 | ret = 0; |
394 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_FRAME_SIZE, 2, | ||
395 | (height_full ? height : (height / 2)), | ||
396 | width); | ||
397 | /* set encoding aspect ratio to 4:3 */ | ||
398 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_ASPECT_RATIO, 1, | ||
399 | 0x02); | ||
400 | 334 | ||
401 | /* VBI */ | 335 | if (!ret) ret = pvr2_encoder_vcmd( |
336 | hdw, CX2341X_ENC_INITIALIZE_INPUT, 0); | ||
402 | 337 | ||
403 | if (hdw->config == pvr2_config_vbi) { | 338 | if (ret) { |
404 | int lines = 2 * (is_30fps ? 12 : 18); | 339 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
405 | int size = (4*((lines*1443+3)/4)) / lines; | 340 | "Failed to initialize cx32416 video input"); |
406 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_VBI_CONFIG, 7, | 341 | return ret; |
407 | 0xbd05, 1, 4, | ||
408 | 0x25256262, 0x387f7f7f, | ||
409 | lines , size); | ||
410 | // 0x25256262, 0x13135454, lines , size); | ||
411 | /* select vbi lines */ | ||
412 | #define line_used(l) (is_30fps ? (l >= 10 && l <= 21) : (l >= 6 && l <= 23)) | ||
413 | for (i = 2 ; i <= 24 ; i++){ | ||
414 | ret |= pvr2_encoder_vcmd( | ||
415 | hdw,CX2341X_ENC_SET_VBI_LINE, 5, | ||
416 | i-1,line_used(i), 0, 0, 0); | ||
417 | ret |= pvr2_encoder_vcmd( | ||
418 | hdw,CX2341X_ENC_SET_VBI_LINE, 5, | ||
419 | (i-1) | (1 << 31), | ||
420 | line_used(i), 0, 0, 0); | ||
421 | } | ||
422 | } else { | ||
423 | ret |= pvr2_encoder_vcmd( | ||
424 | hdw,CX2341X_ENC_SET_VBI_LINE, 5, | ||
425 | 0xffffffff,0,0,0,0); | ||
426 | } | ||
427 | |||
428 | /* set stream type, depending on resolution. */ | ||
429 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_STREAM_TYPE, 1, | ||
430 | height_full ? 0x0a : 0x0b); | ||
431 | /* set video bitrate */ | ||
432 | ret |= pvr2_encoder_vcmd( | ||
433 | hdw, CX2341X_ENC_SET_BIT_RATE, 3, | ||
434 | (hdw->vbr_val ? 1 : 0), | ||
435 | hdw->videobitrate_val, | ||
436 | hdw->videopeak_val / 400); | ||
437 | /* setup GOP structure (GOP size = 0f or 0c, 3-1 = 2 B-frames) */ | ||
438 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_GOP_PROPERTIES, 2, | ||
439 | is_30fps ? 0x0f : 0x0c, 0x03); | ||
440 | |||
441 | /* enable 3:2 pulldown */ | ||
442 | ret |= pvr2_encoder_vcmd(hdw,CX2341X_ENC_SET_3_2_PULLDOWN,1,0); | ||
443 | |||
444 | /* set GOP open/close property (open) */ | ||
445 | ret |= pvr2_encoder_vcmd(hdw,CX2341X_ENC_SET_GOP_CLOSURE,1,0); | ||
446 | |||
447 | /* set audio stream properties 0x40b9? 0100 0000 1011 1001 */ | ||
448 | audio = (pvr_tbl_audiobitrate[hdw->audiobitrate_val] | | ||
449 | pvr_tbl_srate[hdw->srate_val] | | ||
450 | hdw->audiolayer_val << 2 | | ||
451 | (hdw->audiocrc_val ? 1 << 14 : 0) | | ||
452 | pvr_tbl_emphasis[hdw->audioemphasis_val]); | ||
453 | |||
454 | ret |= pvr2_encoder_vcmd(hdw,CX2341X_ENC_SET_AUDIO_PROPERTIES,1, | ||
455 | audio); | ||
456 | |||
457 | /* set dynamic noise reduction filter to manual, Horiz/Vert */ | ||
458 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_DNR_FILTER_MODE, 2, | ||
459 | 0, 0x03); | ||
460 | |||
461 | /* dynamic noise reduction filter param */ | ||
462 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2 | ||
463 | , 0, 0); | ||
464 | |||
465 | /* dynamic noise reduction median filter */ | ||
466 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_SET_CORING_LEVELS, 4, | ||
467 | 0, 0xff, 0, 0xff); | ||
468 | |||
469 | /* spacial prefiler parameter */ | ||
470 | ret |= pvr2_encoder_vcmd(hdw, | ||
471 | CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2, | ||
472 | 0x01, 0x01); | ||
473 | |||
474 | /* initialize video input */ | ||
475 | ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_INITIALIZE_INPUT, 0); | ||
476 | |||
477 | if (!ret) { | ||
478 | hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); | ||
479 | } | 342 | } |
480 | 343 | ||
481 | return ret; | 344 | hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); |
345 | memcpy(&hdw->enc_cur_state,&hdw->enc_ctl_state, | ||
346 | sizeof(struct cx2341x_mpeg_params)); | ||
347 | hdw->enc_cur_valid = !0; | ||
348 | return 0; | ||
482 | } | 349 | } |
483 | 350 | ||
351 | |||
484 | int pvr2_encoder_start(struct pvr2_hdw *hdw) | 352 | int pvr2_encoder_start(struct pvr2_hdw *hdw) |
485 | { | 353 | { |
486 | int status; | 354 | int status; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index 3887190079d1..ba2afbfe32c5 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | |||
@@ -322,6 +322,13 @@ struct pvr2_hdw { | |||
322 | int flag_bilingual; | 322 | int flag_bilingual; |
323 | struct pvr2_audio_stat *audio_stat; | 323 | struct pvr2_audio_stat *audio_stat; |
324 | 324 | ||
325 | /* Control state needed for cx2341x module */ | ||
326 | struct cx2341x_mpeg_params enc_cur_state; | ||
327 | struct cx2341x_mpeg_params enc_ctl_state; | ||
328 | /* True if an encoder attribute has changed */ | ||
329 | int enc_stale; | ||
330 | /* True if enc_cur_state is valid */ | ||
331 | int enc_cur_valid; | ||
325 | 332 | ||
326 | /* Control state */ | 333 | /* Control state */ |
327 | #define VCREATE_DATA(lab) int lab##_val; int lab##_dirty | 334 | #define VCREATE_DATA(lab) int lab##_val; int lab##_dirty |
@@ -339,16 +346,9 @@ struct pvr2_hdw { | |||
339 | VCREATE_DATA(res_hor); | 346 | VCREATE_DATA(res_hor); |
340 | VCREATE_DATA(res_ver); | 347 | VCREATE_DATA(res_ver); |
341 | VCREATE_DATA(srate); | 348 | VCREATE_DATA(srate); |
342 | VCREATE_DATA(audiobitrate); | ||
343 | VCREATE_DATA(audiocrc); | ||
344 | VCREATE_DATA(audioemphasis); | ||
345 | VCREATE_DATA(vbr); | ||
346 | VCREATE_DATA(videobitrate); | ||
347 | VCREATE_DATA(videopeak); | ||
348 | VCREATE_DATA(interlace); | ||
349 | VCREATE_DATA(audiolayer); | ||
350 | #undef VCREATE_DATA | 349 | #undef VCREATE_DATA |
351 | 350 | ||
351 | struct pvr2_ctld_info *mpeg_ctrl_info; | ||
352 | 352 | ||
353 | struct pvr2_ctrl *controls; | 353 | struct pvr2_ctrl *controls; |
354 | unsigned int control_cnt; | 354 | unsigned int control_cnt; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 45faabe96584..7d4799a1c554 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -130,6 +130,98 @@ MODULE_PARM_DESC(tolerance,"specify stream error tolerance"); | |||
130 | /* size of a firmware chunk */ | 130 | /* size of a firmware chunk */ |
131 | #define FIRMWARE_CHUNK_SIZE 0x2000 | 131 | #define FIRMWARE_CHUNK_SIZE 0x2000 |
132 | 132 | ||
133 | /* Define the list of additional controls we'll dynamically construct based | ||
134 | on query of the cx2341x module. */ | ||
135 | struct pvr2_mpeg_ids { | ||
136 | const char *strid; | ||
137 | int id; | ||
138 | }; | ||
139 | static const struct pvr2_mpeg_ids mpeg_ids[] = { | ||
140 | { | ||
141 | .strid = "audio_layer", | ||
142 | .id = V4L2_CID_MPEG_AUDIO_ENCODING, | ||
143 | },{ | ||
144 | .strid = "audio_bitrate", | ||
145 | .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE, | ||
146 | },{ | ||
147 | /* Already using audio_mode elsewhere :-( */ | ||
148 | .strid = "mpeg_audio_mode", | ||
149 | .id = V4L2_CID_MPEG_AUDIO_MODE, | ||
150 | },{ | ||
151 | .strid = "mpeg_audio_mode_extension", | ||
152 | .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION, | ||
153 | },{ | ||
154 | .strid = "audio_emphasis", | ||
155 | .id = V4L2_CID_MPEG_AUDIO_EMPHASIS, | ||
156 | },{ | ||
157 | .strid = "audio_crc", | ||
158 | .id = V4L2_CID_MPEG_AUDIO_CRC, | ||
159 | },{ | ||
160 | .strid = "video_aspect", | ||
161 | .id = V4L2_CID_MPEG_VIDEO_ASPECT, | ||
162 | },{ | ||
163 | .strid = "video_b_frames", | ||
164 | .id = V4L2_CID_MPEG_VIDEO_B_FRAMES, | ||
165 | },{ | ||
166 | .strid = "video_gop_size", | ||
167 | .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE, | ||
168 | },{ | ||
169 | .strid = "video_gop_closure", | ||
170 | .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, | ||
171 | },{ | ||
172 | .strid = "video_pulldown", | ||
173 | .id = V4L2_CID_MPEG_VIDEO_PULLDOWN, | ||
174 | },{ | ||
175 | .strid = "video_bitrate_mode", | ||
176 | .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE, | ||
177 | },{ | ||
178 | .strid = "video_bitrate", | ||
179 | .id = V4L2_CID_MPEG_VIDEO_BITRATE, | ||
180 | },{ | ||
181 | .strid = "video_bitrate_peak", | ||
182 | .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, | ||
183 | },{ | ||
184 | .strid = "video_temporal_decimation", | ||
185 | .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION, | ||
186 | },{ | ||
187 | .strid = "stream_type", | ||
188 | .id = V4L2_CID_MPEG_STREAM_TYPE, | ||
189 | },{ | ||
190 | .strid = "video_spatial_filter_mode", | ||
191 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE, | ||
192 | },{ | ||
193 | .strid = "video_spatial_filter", | ||
194 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER, | ||
195 | },{ | ||
196 | .strid = "video_luma_spatial_filter_type", | ||
197 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE, | ||
198 | },{ | ||
199 | .strid = "video_chroma_spatial_filter_type", | ||
200 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE, | ||
201 | },{ | ||
202 | .strid = "video_temporal_filter_mode", | ||
203 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE, | ||
204 | },{ | ||
205 | .strid = "video_temporal_filter", | ||
206 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER, | ||
207 | },{ | ||
208 | .strid = "video_median_filter_type", | ||
209 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE, | ||
210 | },{ | ||
211 | .strid = "video_luma_median_filter_top", | ||
212 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP, | ||
213 | },{ | ||
214 | .strid = "video_luma_median_filter_bottom", | ||
215 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM, | ||
216 | },{ | ||
217 | .strid = "video_chroma_median_filter_top", | ||
218 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP, | ||
219 | },{ | ||
220 | .strid = "video_chroma_median_filter_bottom", | ||
221 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM, | ||
222 | } | ||
223 | }; | ||
224 | #define MPEGDEF_COUNT (sizeof(mpeg_ids)/sizeof(mpeg_ids[0])) | ||
133 | 225 | ||
134 | static const char *control_values_srate[] = { | 226 | static const char *control_values_srate[] = { |
135 | [PVR2_CVAL_SRATE_48] = "48KHz", | 227 | [PVR2_CVAL_SRATE_48] = "48KHz", |
@@ -137,30 +229,6 @@ static const char *control_values_srate[] = { | |||
137 | }; | 229 | }; |
138 | 230 | ||
139 | 231 | ||
140 | static const char *control_values_audiobitrate[] = { | ||
141 | [PVR2_CVAL_AUDIOBITRATE_384] = "384kb/s", | ||
142 | [PVR2_CVAL_AUDIOBITRATE_320] = "320kb/s", | ||
143 | [PVR2_CVAL_AUDIOBITRATE_256] = "256kb/s", | ||
144 | [PVR2_CVAL_AUDIOBITRATE_224] = "224kb/s", | ||
145 | [PVR2_CVAL_AUDIOBITRATE_192] = "192kb/s", | ||
146 | [PVR2_CVAL_AUDIOBITRATE_160] = "160kb/s", | ||
147 | [PVR2_CVAL_AUDIOBITRATE_128] = "128kb/s", | ||
148 | [PVR2_CVAL_AUDIOBITRATE_112] = "112kb/s", | ||
149 | [PVR2_CVAL_AUDIOBITRATE_96] = "96kb/s", | ||
150 | [PVR2_CVAL_AUDIOBITRATE_80] = "80kb/s", | ||
151 | [PVR2_CVAL_AUDIOBITRATE_64] = "64kb/s", | ||
152 | [PVR2_CVAL_AUDIOBITRATE_56] = "56kb/s", | ||
153 | [PVR2_CVAL_AUDIOBITRATE_48] = "48kb/s", | ||
154 | [PVR2_CVAL_AUDIOBITRATE_32] = "32kb/s", | ||
155 | [PVR2_CVAL_AUDIOBITRATE_VBR] = "VBR", | ||
156 | }; | ||
157 | |||
158 | |||
159 | static const char *control_values_audioemphasis[] = { | ||
160 | [PVR2_CVAL_AUDIOEMPHASIS_NONE] = "None", | ||
161 | [PVR2_CVAL_AUDIOEMPHASIS_50_15] = "50/15us", | ||
162 | [PVR2_CVAL_AUDIOEMPHASIS_CCITT] = "CCITT J.17", | ||
163 | }; | ||
164 | 232 | ||
165 | 233 | ||
166 | static const char *control_values_input[] = { | 234 | static const char *control_values_input[] = { |
@@ -277,6 +345,76 @@ static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v) | |||
277 | return 0; | 345 | return 0; |
278 | } | 346 | } |
279 | 347 | ||
348 | static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr) | ||
349 | { | ||
350 | return cptr->hdw->enc_stale != 0; | ||
351 | } | ||
352 | |||
353 | static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr) | ||
354 | { | ||
355 | cptr->hdw->enc_stale = 0; | ||
356 | } | ||
357 | |||
358 | static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp) | ||
359 | { | ||
360 | int ret; | ||
361 | struct v4l2_ext_controls cs; | ||
362 | struct v4l2_ext_control c1; | ||
363 | memset(&cs,0,sizeof(cs)); | ||
364 | memset(&c1,0,sizeof(c1)); | ||
365 | cs.controls = &c1; | ||
366 | cs.count = 1; | ||
367 | c1.id = cptr->info->v4l_id; | ||
368 | ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs, | ||
369 | VIDIOC_G_EXT_CTRLS); | ||
370 | if (ret) return ret; | ||
371 | *vp = c1.value; | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v) | ||
376 | { | ||
377 | int ret; | ||
378 | struct v4l2_ext_controls cs; | ||
379 | struct v4l2_ext_control c1; | ||
380 | memset(&cs,0,sizeof(cs)); | ||
381 | memset(&c1,0,sizeof(c1)); | ||
382 | cs.controls = &c1; | ||
383 | cs.count = 1; | ||
384 | c1.id = cptr->info->v4l_id; | ||
385 | c1.value = v; | ||
386 | ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs, | ||
387 | VIDIOC_S_EXT_CTRLS); | ||
388 | if (ret) return ret; | ||
389 | cptr->hdw->enc_stale = !0; | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr) | ||
394 | { | ||
395 | struct v4l2_queryctrl qctrl; | ||
396 | struct pvr2_ctl_info *info; | ||
397 | qctrl.id = cptr->info->v4l_id; | ||
398 | cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl); | ||
399 | /* Strip out the const so we can adjust a function pointer. It's | ||
400 | OK to do this here because we know this is a dynamically created | ||
401 | control, so the underlying storage for the info pointer is (a) | ||
402 | private to us, and (b) not in read-only storage. Either we do | ||
403 | this or we significantly complicate the underlying control | ||
404 | implementation. */ | ||
405 | info = (struct pvr2_ctl_info *)(cptr->info); | ||
406 | if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) { | ||
407 | if (info->set_value) { | ||
408 | info->set_value = 0; | ||
409 | } | ||
410 | } else { | ||
411 | if (!(info->set_value)) { | ||
412 | info->set_value = ctrl_cx2341x_set; | ||
413 | } | ||
414 | } | ||
415 | return qctrl.flags; | ||
416 | } | ||
417 | |||
280 | static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp) | 418 | static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp) |
281 | { | 419 | { |
282 | *vp = cptr->hdw->flag_streaming_enabled; | 420 | *vp = cptr->hdw->flag_streaming_enabled; |
@@ -475,14 +613,6 @@ VCREATE_FUNCS(audiomode) | |||
475 | VCREATE_FUNCS(res_hor) | 613 | VCREATE_FUNCS(res_hor) |
476 | VCREATE_FUNCS(res_ver) | 614 | VCREATE_FUNCS(res_ver) |
477 | VCREATE_FUNCS(srate) | 615 | VCREATE_FUNCS(srate) |
478 | VCREATE_FUNCS(audiobitrate) | ||
479 | VCREATE_FUNCS(audiocrc) | ||
480 | VCREATE_FUNCS(audioemphasis) | ||
481 | VCREATE_FUNCS(vbr) | ||
482 | VCREATE_FUNCS(videobitrate) | ||
483 | VCREATE_FUNCS(videopeak) | ||
484 | VCREATE_FUNCS(interlace) | ||
485 | VCREATE_FUNCS(audiolayer) | ||
486 | 616 | ||
487 | #define MIN_FREQ 55250000L | 617 | #define MIN_FREQ 55250000L |
488 | #define MAX_FREQ 850000000L | 618 | #define MAX_FREQ 850000000L |
@@ -581,68 +711,13 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
581 | DEFREF(res_ver), | 711 | DEFREF(res_ver), |
582 | DEFINT(200,625), | 712 | DEFINT(200,625), |
583 | },{ | 713 | },{ |
584 | .v4l_id = V4L2_CID_PVR_SRATE, | 714 | .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, |
585 | .desc = "Sample rate", | 715 | .desc = "Sample rate", |
586 | .name = "srate", | 716 | .name = "srate", |
587 | .default_value = PVR2_CVAL_SRATE_48, | 717 | .default_value = PVR2_CVAL_SRATE_48, |
588 | DEFREF(srate), | 718 | DEFREF(srate), |
589 | DEFENUM(control_values_srate), | 719 | DEFENUM(control_values_srate), |
590 | },{ | 720 | },{ |
591 | .v4l_id = V4L2_CID_PVR_AUDIOBITRATE, | ||
592 | .desc = "Audio Bitrate", | ||
593 | .name = "audio_bitrate", | ||
594 | .default_value = PVR2_CVAL_AUDIOBITRATE_224, | ||
595 | DEFREF(audiobitrate), | ||
596 | DEFENUM(control_values_audiobitrate), | ||
597 | },{ | ||
598 | .v4l_id = V4L2_CID_PVR_AUDIOCRC, | ||
599 | .desc = "Audio CRC", | ||
600 | .name = "audio_crc", | ||
601 | .default_value = 1, | ||
602 | DEFREF(audiocrc), | ||
603 | DEFBOOL, | ||
604 | },{ | ||
605 | .v4l_id = V4L2_CID_PVR_AUDIOEMPHASIS, | ||
606 | .desc = "Audio Emphasis", | ||
607 | .name = "audio_emphasis", | ||
608 | .default_value = PVR2_CVAL_AUDIOEMPHASIS_NONE, | ||
609 | DEFREF(audioemphasis), | ||
610 | DEFENUM(control_values_audioemphasis), | ||
611 | },{ | ||
612 | .v4l_id = V4L2_CID_PVR_VBR, | ||
613 | .desc = "Variable video bitrate", | ||
614 | .name = "vbr", | ||
615 | .default_value = 0, | ||
616 | DEFREF(vbr), | ||
617 | DEFBOOL, | ||
618 | },{ | ||
619 | .v4l_id = V4L2_CID_PVR_VIDEOBITRATE, | ||
620 | .desc = "Average video bitrate", | ||
621 | .name = "video_average_bitrate", | ||
622 | .default_value = 6000000, | ||
623 | DEFREF(videobitrate), | ||
624 | DEFINT(500000,20000000), | ||
625 | },{ | ||
626 | .v4l_id = V4L2_CID_PVR_VIDEOPEAK, | ||
627 | .desc = "Peak video bitrate", | ||
628 | .name = "video_peak_bitrate", | ||
629 | .default_value = 6000000, | ||
630 | DEFREF(videopeak), | ||
631 | DEFINT(500000,20000000), | ||
632 | },{ | ||
633 | .desc = "Interlace mode", | ||
634 | .name = "interlace", | ||
635 | .internal_id = PVR2_CID_INTERLACE, | ||
636 | .default_value = 0, | ||
637 | DEFREF(interlace), | ||
638 | DEFBOOL, | ||
639 | },{ | ||
640 | .desc = "Audio Layer", | ||
641 | .name = "audio_layer", | ||
642 | .default_value = 2, | ||
643 | DEFREF(audiolayer), | ||
644 | DEFINT(0,3), | ||
645 | },{ | ||
646 | .desc = "Tuner Frequency (Hz)", | 721 | .desc = "Tuner Frequency (Hz)", |
647 | .name = "frequency", | 722 | .name = "frequency", |
648 | .internal_id = PVR2_CID_FREQUENCY, | 723 | .internal_id = PVR2_CID_FREQUENCY, |
@@ -958,6 +1033,10 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
958 | if (ret < 0) return ret; | 1033 | if (ret < 0) return ret; |
959 | fwidx = ret; | 1034 | fwidx = ret; |
960 | ret = 0; | 1035 | ret = 0; |
1036 | /* Since we're about to completely reinitialize the encoder, | ||
1037 | invalidate our cached copy of its configuration state. Next | ||
1038 | time we configure the encoder, then we'll fully configure it. */ | ||
1039 | hdw->enc_cur_valid = 0; | ||
961 | 1040 | ||
962 | /* First prepare firmware loading */ | 1041 | /* First prepare firmware loading */ |
963 | ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/ | 1042 | ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/ |
@@ -1654,6 +1733,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1654 | int valid_std_mask; | 1733 | int valid_std_mask; |
1655 | struct pvr2_ctrl *cptr; | 1734 | struct pvr2_ctrl *cptr; |
1656 | __u8 ifnum; | 1735 | __u8 ifnum; |
1736 | struct v4l2_queryctrl qctrl; | ||
1737 | struct pvr2_ctl_info *ciptr; | ||
1657 | 1738 | ||
1658 | hdw_type = devid - pvr2_device_table; | 1739 | hdw_type = devid - pvr2_device_table; |
1659 | if (hdw_type >= | 1740 | if (hdw_type >= |
@@ -1668,8 +1749,10 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1668 | hdw,pvr2_device_names[hdw_type]); | 1749 | hdw,pvr2_device_names[hdw_type]); |
1669 | if (!hdw) goto fail; | 1750 | if (!hdw) goto fail; |
1670 | memset(hdw,0,sizeof(*hdw)); | 1751 | memset(hdw,0,sizeof(*hdw)); |
1752 | cx2341x_fill_defaults(&hdw->enc_ctl_state); | ||
1671 | 1753 | ||
1672 | hdw->control_cnt = CTRLDEF_COUNT; | 1754 | hdw->control_cnt = CTRLDEF_COUNT; |
1755 | hdw->control_cnt += MPEGDEF_COUNT; | ||
1673 | hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt, | 1756 | hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt, |
1674 | GFP_KERNEL); | 1757 | GFP_KERNEL); |
1675 | if (!hdw->controls) goto fail; | 1758 | if (!hdw->controls) goto fail; |
@@ -1686,6 +1769,54 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1686 | cptr = hdw->controls + idx; | 1769 | cptr = hdw->controls + idx; |
1687 | cptr->info = control_defs+idx; | 1770 | cptr->info = control_defs+idx; |
1688 | } | 1771 | } |
1772 | /* Define and configure additional controls from cx2341x module. */ | ||
1773 | hdw->mpeg_ctrl_info = kmalloc( | ||
1774 | sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL); | ||
1775 | if (!hdw->mpeg_ctrl_info) goto fail; | ||
1776 | memset(hdw->mpeg_ctrl_info,0, | ||
1777 | sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT); | ||
1778 | for (idx = 0; idx < MPEGDEF_COUNT; idx++) { | ||
1779 | cptr = hdw->controls + idx + CTRLDEF_COUNT; | ||
1780 | ciptr = &(hdw->mpeg_ctrl_info[idx].info); | ||
1781 | ciptr->desc = hdw->mpeg_ctrl_info[idx].desc; | ||
1782 | ciptr->name = mpeg_ids[idx].strid; | ||
1783 | ciptr->v4l_id = mpeg_ids[idx].id; | ||
1784 | ciptr->skip_init = !0; | ||
1785 | ciptr->get_value = ctrl_cx2341x_get; | ||
1786 | ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags; | ||
1787 | ciptr->is_dirty = ctrl_cx2341x_is_dirty; | ||
1788 | if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty; | ||
1789 | qctrl.id = ciptr->v4l_id; | ||
1790 | cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl); | ||
1791 | if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) { | ||
1792 | ciptr->set_value = ctrl_cx2341x_set; | ||
1793 | } | ||
1794 | strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name, | ||
1795 | PVR2_CTLD_INFO_DESC_SIZE); | ||
1796 | hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0; | ||
1797 | ciptr->default_value = qctrl.default_value; | ||
1798 | switch (qctrl.type) { | ||
1799 | default: | ||
1800 | case V4L2_CTRL_TYPE_INTEGER: | ||
1801 | ciptr->type = pvr2_ctl_int; | ||
1802 | ciptr->def.type_int.min_value = qctrl.minimum; | ||
1803 | ciptr->def.type_int.max_value = qctrl.maximum; | ||
1804 | break; | ||
1805 | case V4L2_CTRL_TYPE_BOOLEAN: | ||
1806 | ciptr->type = pvr2_ctl_bool; | ||
1807 | break; | ||
1808 | case V4L2_CTRL_TYPE_MENU: | ||
1809 | ciptr->type = pvr2_ctl_enum; | ||
1810 | ciptr->def.type_enum.value_names = | ||
1811 | cx2341x_ctrl_get_menu(ciptr->v4l_id); | ||
1812 | for (cnt1 = 0; | ||
1813 | ciptr->def.type_enum.value_names[cnt1] != NULL; | ||
1814 | cnt1++) { } | ||
1815 | ciptr->def.type_enum.count = cnt1; | ||
1816 | break; | ||
1817 | } | ||
1818 | cptr->info = ciptr; | ||
1819 | } | ||
1689 | 1820 | ||
1690 | // Initialize video standard enum dynamic control | 1821 | // Initialize video standard enum dynamic control |
1691 | cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM); | 1822 | cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM); |
@@ -1788,6 +1919,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1788 | if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer); | 1919 | if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer); |
1789 | if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer); | 1920 | if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer); |
1790 | if (hdw->controls) kfree(hdw->controls); | 1921 | if (hdw->controls) kfree(hdw->controls); |
1922 | if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info); | ||
1791 | kfree(hdw); | 1923 | kfree(hdw); |
1792 | } | 1924 | } |
1793 | return 0; | 1925 | return 0; |
@@ -1853,6 +1985,7 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) | |||
1853 | } | 1985 | } |
1854 | } while (0); up(&pvr2_unit_sem); | 1986 | } while (0); up(&pvr2_unit_sem); |
1855 | if (hdw->controls) kfree(hdw->controls); | 1987 | if (hdw->controls) kfree(hdw->controls); |
1988 | if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info); | ||
1856 | if (hdw->std_defs) kfree(hdw->std_defs); | 1989 | if (hdw->std_defs) kfree(hdw->std_defs); |
1857 | if (hdw->std_enum_names) kfree(hdw->std_enum_names); | 1990 | if (hdw->std_enum_names) kfree(hdw->std_enum_names); |
1858 | kfree(hdw); | 1991 | kfree(hdw); |
@@ -2104,10 +2237,6 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) | |||
2104 | hdw->res_ver_val = nvres; | 2237 | hdw->res_ver_val = nvres; |
2105 | hdw->res_ver_dirty = !0; | 2238 | hdw->res_ver_dirty = !0; |
2106 | } | 2239 | } |
2107 | if (!hdw->interlace_val) { | ||
2108 | hdw->interlace_val = 0; | ||
2109 | hdw->interlace_dirty = !0; | ||
2110 | } | ||
2111 | } | 2240 | } |
2112 | 2241 | ||
2113 | if (hdw->std_dirty || | 2242 | if (hdw->std_dirty || |
@@ -2118,6 +2247,21 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) | |||
2118 | stale_subsys_mask |= hdw->subsys_stream_mask; | 2247 | stale_subsys_mask |= hdw->subsys_stream_mask; |
2119 | } | 2248 | } |
2120 | 2249 | ||
2250 | if (hdw->srate_dirty) { | ||
2251 | /* Write new sample rate into control structure since | ||
2252 | * the master copy is stale. We must track srate | ||
2253 | * separate from the mpeg control structure because | ||
2254 | * other logic also uses this value. */ | ||
2255 | struct v4l2_ext_controls cs; | ||
2256 | struct v4l2_ext_control c1; | ||
2257 | memset(&cs,0,sizeof(cs)); | ||
2258 | memset(&c1,0,sizeof(c1)); | ||
2259 | cs.controls = &c1; | ||
2260 | cs.count = 1; | ||
2261 | c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ; | ||
2262 | c1.value = hdw->srate_val; | ||
2263 | cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS); | ||
2264 | } | ||
2121 | 2265 | ||
2122 | /* Scan i2c core at this point - before we clear all the dirty | 2266 | /* Scan i2c core at this point - before we clear all the dirty |
2123 | bits. Various parts of the i2c core will notice dirty bits as | 2267 | bits. Various parts of the i2c core will notice dirty bits as |
@@ -2262,6 +2406,8 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw) | |||
2262 | pvr2_i2c_core_check_stale(hdw); | 2406 | pvr2_i2c_core_check_stale(hdw); |
2263 | hdw->log_requested = 0; | 2407 | hdw->log_requested = 0; |
2264 | pvr2_i2c_core_sync(hdw); | 2408 | pvr2_i2c_core_sync(hdw); |
2409 | pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:"); | ||
2410 | cx2341x_log_status(&hdw->enc_ctl_state,0); | ||
2265 | printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr); | 2411 | printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr); |
2266 | } while (0); LOCK_GIVE(hdw->big_lock); | 2412 | } while (0); LOCK_GIVE(hdw->big_lock); |
2267 | } | 2413 | } |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 779c27ea188e..63f529154431 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h | |||
@@ -26,16 +26,6 @@ | |||
26 | #include "pvrusb2-io.h" | 26 | #include "pvrusb2-io.h" |
27 | #include "pvrusb2-ctrl.h" | 27 | #include "pvrusb2-ctrl.h" |
28 | 28 | ||
29 | /* Private V4L2-compatible controls available in this driver, look these up | ||
30 | with pvr2_hdw_get_ctrl_v4l(). */ | ||
31 | #define V4L2_CID_PVR_SRATE (V4L2_CID_PRIVATE_BASE) | ||
32 | #define V4L2_CID_PVR_AUDIOBITRATE (V4L2_CID_PRIVATE_BASE+1) | ||
33 | #define V4L2_CID_PVR_AUDIOCRC (V4L2_CID_PRIVATE_BASE+2) | ||
34 | #define V4L2_CID_PVR_AUDIOEMPHASIS (V4L2_CID_PRIVATE_BASE+3) | ||
35 | #define V4L2_CID_PVR_VBR (V4L2_CID_PRIVATE_BASE+4) | ||
36 | #define V4L2_CID_PVR_VIDEOBITRATE (V4L2_CID_PRIVATE_BASE+5) | ||
37 | #define V4L2_CID_PVR_VIDEOPEAK (V4L2_CID_PRIVATE_BASE+6) | ||
38 | #define V4L2_CID_PVR_VIDEOSTANDARD (V4L2_CID_PRIVATE_BASE+7) | ||
39 | 29 | ||
40 | /* Private internal control ids, look these up with | 30 | /* Private internal control ids, look these up with |
41 | pvr2_hdw_get_ctrl_by_id() - these are NOT visible in V4L */ | 31 | pvr2_hdw_get_ctrl_by_id() - these are NOT visible in V4L */ |
@@ -47,7 +37,6 @@ | |||
47 | #define PVR2_CID_FREQUENCY 6 | 37 | #define PVR2_CID_FREQUENCY 6 |
48 | #define PVR2_CID_HRES 7 | 38 | #define PVR2_CID_HRES 7 |
49 | #define PVR2_CID_VRES 8 | 39 | #define PVR2_CID_VRES 8 |
50 | #define PVR2_CID_INTERLACE 9 | ||
51 | 40 | ||
52 | /* Legal values for the INPUT state variable */ | 41 | /* Legal values for the INPUT state variable */ |
53 | #define PVR2_CVAL_INPUT_TV 0 | 42 | #define PVR2_CVAL_INPUT_TV 0 |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c index 4127c82f7bf6..e4ec7f25194c 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c +++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c | |||
@@ -91,12 +91,15 @@ static void set_audio(struct pvr2_v4l_decoder *ctxt) | |||
91 | hdw->srate_val); | 91 | hdw->srate_val); |
92 | switch (hdw->srate_val) { | 92 | switch (hdw->srate_val) { |
93 | default: | 93 | default: |
94 | case PVR2_CVAL_SRATE_48: | 94 | case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: |
95 | val = 48000; | 95 | val = 48000; |
96 | break; | 96 | break; |
97 | case PVR2_CVAL_SRATE_44_1: | 97 | case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: |
98 | val = 44100; | 98 | val = 44100; |
99 | break; | 99 | break; |
100 | case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: | ||
101 | val = 32000; | ||
102 | break; | ||
100 | } | 103 | } |
101 | pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); | 104 | pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); |
102 | } | 105 | } |