aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2006-06-25 19:05:01 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-06-26 23:17:32 -0400
commitb30d244176846de3480ae17097a5f7831ec6aaf6 (patch)
treefba5650757a84032802b87635b7fe41d77c8e3cd /drivers/media
parent1d9f8461f1a870571f9403a312c26deec3305be5 (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/media')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c7
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c228
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h16
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c330
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h11
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c7
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
30static 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
36static u32 pvr_tbl_srate[] = {
37 [PVR2_CVAL_SRATE_48] = 0x01,
38 [PVR2_CVAL_SRATE_44_1] = 0x00,
39};
40
41static 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
320int pvr2_encoder_configure(struct pvr2_hdw *hdw) 291int 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
484int pvr2_encoder_start(struct pvr2_hdw *hdw) 352int 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. */
135struct pvr2_mpeg_ids {
136 const char *strid;
137 int id;
138};
139static 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
134static const char *control_values_srate[] = { 226static 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
140static 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
159static 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
166static const char *control_values_input[] = { 234static 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
348static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
349{
350 return cptr->hdw->enc_stale != 0;
351}
352
353static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
354{
355 cptr->hdw->enc_stale = 0;
356}
357
358static 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
375static 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
393static 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
280static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp) 418static 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)
475VCREATE_FUNCS(res_hor) 613VCREATE_FUNCS(res_hor)
476VCREATE_FUNCS(res_ver) 614VCREATE_FUNCS(res_ver)
477VCREATE_FUNCS(srate) 615VCREATE_FUNCS(srate)
478VCREATE_FUNCS(audiobitrate)
479VCREATE_FUNCS(audiocrc)
480VCREATE_FUNCS(audioemphasis)
481VCREATE_FUNCS(vbr)
482VCREATE_FUNCS(videobitrate)
483VCREATE_FUNCS(videopeak)
484VCREATE_FUNCS(interlace)
485VCREATE_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}