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/media/video/pvrusb2/pvrusb2-hdw.c | |
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/media/video/pvrusb2/pvrusb2-hdw.c')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 330 |
1 files changed, 238 insertions, 92 deletions
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 | } |