diff options
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-hdw.c')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 501 |
1 files changed, 327 insertions, 174 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index d2004965187b..a1ca0f5007e0 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -36,6 +36,10 @@ | |||
36 | #include "pvrusb2-hdw-internal.h" | 36 | #include "pvrusb2-hdw-internal.h" |
37 | #include "pvrusb2-encoder.h" | 37 | #include "pvrusb2-encoder.h" |
38 | #include "pvrusb2-debug.h" | 38 | #include "pvrusb2-debug.h" |
39 | #include "pvrusb2-fx2-cmd.h" | ||
40 | |||
41 | #define TV_MIN_FREQ 55250000L | ||
42 | #define TV_MAX_FREQ 850000000L | ||
39 | 43 | ||
40 | struct usb_device_id pvr2_device_table[] = { | 44 | struct usb_device_id pvr2_device_table[] = { |
41 | [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) }, | 45 | [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) }, |
@@ -71,12 +75,10 @@ static const char *pvr2_client_29xxx[] = { | |||
71 | 75 | ||
72 | static struct pvr2_string_table pvr2_client_lists[] = { | 76 | static struct pvr2_string_table pvr2_client_lists[] = { |
73 | [PVR2_HDW_TYPE_29XXX] = { | 77 | [PVR2_HDW_TYPE_29XXX] = { |
74 | pvr2_client_29xxx, | 78 | pvr2_client_29xxx, ARRAY_SIZE(pvr2_client_29xxx) |
75 | sizeof(pvr2_client_29xxx)/sizeof(pvr2_client_29xxx[0]), | ||
76 | }, | 79 | }, |
77 | [PVR2_HDW_TYPE_24XXX] = { | 80 | [PVR2_HDW_TYPE_24XXX] = { |
78 | pvr2_client_24xxx, | 81 | pvr2_client_24xxx, ARRAY_SIZE(pvr2_client_24xxx) |
79 | sizeof(pvr2_client_24xxx)/sizeof(pvr2_client_24xxx[0]), | ||
80 | }, | 82 | }, |
81 | }; | 83 | }; |
82 | 84 | ||
@@ -160,9 +162,6 @@ static const struct pvr2_mpeg_ids mpeg_ids[] = { | |||
160 | .strid = "video_gop_closure", | 162 | .strid = "video_gop_closure", |
161 | .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, | 163 | .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, |
162 | },{ | 164 | },{ |
163 | .strid = "video_pulldown", | ||
164 | .id = V4L2_CID_MPEG_VIDEO_PULLDOWN, | ||
165 | },{ | ||
166 | .strid = "video_bitrate_mode", | 165 | .strid = "video_bitrate_mode", |
167 | .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE, | 166 | .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE, |
168 | },{ | 167 | },{ |
@@ -212,7 +211,7 @@ static const struct pvr2_mpeg_ids mpeg_ids[] = { | |||
212 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM, | 211 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM, |
213 | } | 212 | } |
214 | }; | 213 | }; |
215 | #define MPEGDEF_COUNT (sizeof(mpeg_ids)/sizeof(mpeg_ids[0])) | 214 | #define MPEGDEF_COUNT ARRAY_SIZE(mpeg_ids) |
216 | 215 | ||
217 | 216 | ||
218 | static const char *control_values_srate[] = { | 217 | static const char *control_values_srate[] = { |
@@ -255,10 +254,10 @@ static const char *control_values_subsystem[] = { | |||
255 | [PVR2_SUBSYS_B_ENC_RUN] = "enc_run", | 254 | [PVR2_SUBSYS_B_ENC_RUN] = "enc_run", |
256 | }; | 255 | }; |
257 | 256 | ||
257 | static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long); | ||
258 | static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); | 258 | static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); |
259 | static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw); | 259 | static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw); |
260 | static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw); | 260 | static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw); |
261 | static unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw); | ||
262 | static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); | 261 | static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); |
263 | static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); | 262 | static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); |
264 | static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw); | 263 | static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw); |
@@ -272,8 +271,6 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, | |||
272 | unsigned int timeout,int probe_fl, | 271 | unsigned int timeout,int probe_fl, |
273 | void *write_data,unsigned int write_len, | 272 | void *write_data,unsigned int write_len, |
274 | void *read_data,unsigned int read_len); | 273 | void *read_data,unsigned int read_len); |
275 | static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res); | ||
276 | static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res); | ||
277 | 274 | ||
278 | static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp) | 275 | static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp) |
279 | { | 276 | { |
@@ -289,8 +286,21 @@ static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp) | |||
289 | static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v) | 286 | static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v) |
290 | { | 287 | { |
291 | struct pvr2_hdw *hdw = cptr->hdw; | 288 | struct pvr2_hdw *hdw = cptr->hdw; |
292 | if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) { | 289 | unsigned int slotId = hdw->freqProgSlot; |
293 | hdw->freqTable[hdw->freqProgSlot-1] = v; | 290 | if ((slotId > 0) && (slotId <= FREQTABLE_SIZE)) { |
291 | hdw->freqTable[slotId-1] = v; | ||
292 | /* Handle side effects correctly - if we're tuned to this | ||
293 | slot, then forgot the slot id relation since the stored | ||
294 | frequency has been changed. */ | ||
295 | if (hdw->freqSelector) { | ||
296 | if (hdw->freqSlotRadio == slotId) { | ||
297 | hdw->freqSlotRadio = 0; | ||
298 | } | ||
299 | } else { | ||
300 | if (hdw->freqSlotTelevision == slotId) { | ||
301 | hdw->freqSlotTelevision = 0; | ||
302 | } | ||
303 | } | ||
294 | } | 304 | } |
295 | return 0; | 305 | return 0; |
296 | } | 306 | } |
@@ -312,28 +322,32 @@ static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v) | |||
312 | 322 | ||
313 | static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp) | 323 | static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp) |
314 | { | 324 | { |
315 | *vp = cptr->hdw->freqSlot; | 325 | struct pvr2_hdw *hdw = cptr->hdw; |
326 | *vp = hdw->freqSelector ? hdw->freqSlotRadio : hdw->freqSlotTelevision; | ||
316 | return 0; | 327 | return 0; |
317 | } | 328 | } |
318 | 329 | ||
319 | static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int v) | 330 | static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int slotId) |
320 | { | 331 | { |
321 | unsigned freq = 0; | 332 | unsigned freq = 0; |
322 | struct pvr2_hdw *hdw = cptr->hdw; | 333 | struct pvr2_hdw *hdw = cptr->hdw; |
323 | hdw->freqSlot = v; | 334 | if ((slotId < 0) || (slotId > FREQTABLE_SIZE)) return 0; |
324 | if ((hdw->freqSlot > 0) && (hdw->freqSlot <= FREQTABLE_SIZE)) { | 335 | if (slotId > 0) { |
325 | freq = hdw->freqTable[hdw->freqSlot-1]; | 336 | freq = hdw->freqTable[slotId-1]; |
326 | } | 337 | if (!freq) return 0; |
327 | if (freq && (freq != hdw->freqVal)) { | 338 | pvr2_hdw_set_cur_freq(hdw,freq); |
328 | hdw->freqVal = freq; | 339 | } |
329 | hdw->freqDirty = !0; | 340 | if (hdw->freqSelector) { |
341 | hdw->freqSlotRadio = slotId; | ||
342 | } else { | ||
343 | hdw->freqSlotTelevision = slotId; | ||
330 | } | 344 | } |
331 | return 0; | 345 | return 0; |
332 | } | 346 | } |
333 | 347 | ||
334 | static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp) | 348 | static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp) |
335 | { | 349 | { |
336 | *vp = cptr->hdw->freqVal; | 350 | *vp = pvr2_hdw_get_cur_freq(cptr->hdw); |
337 | return 0; | 351 | return 0; |
338 | } | 352 | } |
339 | 353 | ||
@@ -349,10 +363,7 @@ static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr) | |||
349 | 363 | ||
350 | static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v) | 364 | static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v) |
351 | { | 365 | { |
352 | struct pvr2_hdw *hdw = cptr->hdw; | 366 | pvr2_hdw_set_cur_freq(cptr->hdw,v); |
353 | hdw->freqVal = v; | ||
354 | hdw->freqDirty = !0; | ||
355 | hdw->freqSlot = 0; | ||
356 | return 0; | 367 | return 0; |
357 | } | 368 | } |
358 | 369 | ||
@@ -378,6 +389,89 @@ static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp) | |||
378 | return 0; | 389 | return 0; |
379 | } | 390 | } |
380 | 391 | ||
392 | static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp) | ||
393 | { | ||
394 | *vp = cptr->hdw->input_val; | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v) | ||
399 | { | ||
400 | struct pvr2_hdw *hdw = cptr->hdw; | ||
401 | |||
402 | if (hdw->input_val != v) { | ||
403 | hdw->input_val = v; | ||
404 | hdw->input_dirty = !0; | ||
405 | } | ||
406 | |||
407 | /* Handle side effects - if we switch to a mode that needs the RF | ||
408 | tuner, then select the right frequency choice as well and mark | ||
409 | it dirty. */ | ||
410 | if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { | ||
411 | hdw->freqSelector = 0; | ||
412 | hdw->freqDirty = !0; | ||
413 | } else if (hdw->input_val == PVR2_CVAL_INPUT_TV) { | ||
414 | hdw->freqSelector = 1; | ||
415 | hdw->freqDirty = !0; | ||
416 | } | ||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | static int ctrl_isdirty_input(struct pvr2_ctrl *cptr) | ||
421 | { | ||
422 | return cptr->hdw->input_dirty != 0; | ||
423 | } | ||
424 | |||
425 | static void ctrl_cleardirty_input(struct pvr2_ctrl *cptr) | ||
426 | { | ||
427 | cptr->hdw->input_dirty = 0; | ||
428 | } | ||
429 | |||
430 | |||
431 | static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp) | ||
432 | { | ||
433 | unsigned long fv; | ||
434 | struct pvr2_hdw *hdw = cptr->hdw; | ||
435 | if (hdw->tuner_signal_stale) { | ||
436 | pvr2_i2c_core_status_poll(hdw); | ||
437 | } | ||
438 | fv = hdw->tuner_signal_info.rangehigh; | ||
439 | if (!fv) { | ||
440 | /* Safety fallback */ | ||
441 | *vp = TV_MAX_FREQ; | ||
442 | return 0; | ||
443 | } | ||
444 | if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) { | ||
445 | fv = (fv * 125) / 2; | ||
446 | } else { | ||
447 | fv = fv * 62500; | ||
448 | } | ||
449 | *vp = fv; | ||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp) | ||
454 | { | ||
455 | unsigned long fv; | ||
456 | struct pvr2_hdw *hdw = cptr->hdw; | ||
457 | if (hdw->tuner_signal_stale) { | ||
458 | pvr2_i2c_core_status_poll(hdw); | ||
459 | } | ||
460 | fv = hdw->tuner_signal_info.rangelow; | ||
461 | if (!fv) { | ||
462 | /* Safety fallback */ | ||
463 | *vp = TV_MIN_FREQ; | ||
464 | return 0; | ||
465 | } | ||
466 | if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) { | ||
467 | fv = (fv * 125) / 2; | ||
468 | } else { | ||
469 | fv = fv * 62500; | ||
470 | } | ||
471 | *vp = fv; | ||
472 | return 0; | ||
473 | } | ||
474 | |||
381 | static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr) | 475 | static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr) |
382 | { | 476 | { |
383 | return cptr->hdw->enc_stale != 0; | 477 | return cptr->hdw->enc_stale != 0; |
@@ -534,8 +628,32 @@ static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr) | |||
534 | 628 | ||
535 | static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp) | 629 | static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp) |
536 | { | 630 | { |
537 | *vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) & | 631 | struct pvr2_hdw *hdw = cptr->hdw; |
538 | PVR2_SIGNAL_OK) ? 1 : 0); | 632 | pvr2_i2c_core_status_poll(hdw); |
633 | *vp = hdw->tuner_signal_info.signal; | ||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp) | ||
638 | { | ||
639 | int val = 0; | ||
640 | unsigned int subchan; | ||
641 | struct pvr2_hdw *hdw = cptr->hdw; | ||
642 | pvr2_i2c_core_status_poll(hdw); | ||
643 | subchan = hdw->tuner_signal_info.rxsubchans; | ||
644 | if (subchan & V4L2_TUNER_SUB_MONO) { | ||
645 | val |= (1 << V4L2_TUNER_MODE_MONO); | ||
646 | } | ||
647 | if (subchan & V4L2_TUNER_SUB_STEREO) { | ||
648 | val |= (1 << V4L2_TUNER_MODE_STEREO); | ||
649 | } | ||
650 | if (subchan & V4L2_TUNER_SUB_LANG1) { | ||
651 | val |= (1 << V4L2_TUNER_MODE_LANG1); | ||
652 | } | ||
653 | if (subchan & V4L2_TUNER_SUB_LANG2) { | ||
654 | val |= (1 << V4L2_TUNER_MODE_LANG2); | ||
655 | } | ||
656 | *vp = val; | ||
539 | return 0; | 657 | return 0; |
540 | } | 658 | } |
541 | 659 | ||
@@ -604,7 +722,7 @@ static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr) | |||
604 | 722 | ||
605 | #define DEFENUM(tab) \ | 723 | #define DEFENUM(tab) \ |
606 | .type = pvr2_ctl_enum, \ | 724 | .type = pvr2_ctl_enum, \ |
607 | .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \ | 725 | .def.type_enum.count = ARRAY_SIZE(tab), \ |
608 | .def.type_enum.value_names = tab | 726 | .def.type_enum.value_names = tab |
609 | 727 | ||
610 | #define DEFBOOL \ | 728 | #define DEFBOOL \ |
@@ -641,15 +759,11 @@ VCREATE_FUNCS(balance) | |||
641 | VCREATE_FUNCS(bass) | 759 | VCREATE_FUNCS(bass) |
642 | VCREATE_FUNCS(treble) | 760 | VCREATE_FUNCS(treble) |
643 | VCREATE_FUNCS(mute) | 761 | VCREATE_FUNCS(mute) |
644 | VCREATE_FUNCS(input) | ||
645 | VCREATE_FUNCS(audiomode) | 762 | VCREATE_FUNCS(audiomode) |
646 | VCREATE_FUNCS(res_hor) | 763 | VCREATE_FUNCS(res_hor) |
647 | VCREATE_FUNCS(res_ver) | 764 | VCREATE_FUNCS(res_ver) |
648 | VCREATE_FUNCS(srate) | 765 | VCREATE_FUNCS(srate) |
649 | 766 | ||
650 | #define MIN_FREQ 55250000L | ||
651 | #define MAX_FREQ 850000000L | ||
652 | |||
653 | /* Table definition of all controls which can be manipulated */ | 767 | /* Table definition of all controls which can be manipulated */ |
654 | static const struct pvr2_ctl_info control_defs[] = { | 768 | static const struct pvr2_ctl_info control_defs[] = { |
655 | { | 769 | { |
@@ -684,7 +798,7 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
684 | .v4l_id = V4L2_CID_AUDIO_VOLUME, | 798 | .v4l_id = V4L2_CID_AUDIO_VOLUME, |
685 | .desc = "Volume", | 799 | .desc = "Volume", |
686 | .name = "volume", | 800 | .name = "volume", |
687 | .default_value = 65535, | 801 | .default_value = 62000, |
688 | DEFREF(volume), | 802 | DEFREF(volume), |
689 | DEFINT(0,65535), | 803 | DEFINT(0,65535), |
690 | },{ | 804 | },{ |
@@ -758,12 +872,16 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
758 | .desc = "Tuner Frequency (Hz)", | 872 | .desc = "Tuner Frequency (Hz)", |
759 | .name = "frequency", | 873 | .name = "frequency", |
760 | .internal_id = PVR2_CID_FREQUENCY, | 874 | .internal_id = PVR2_CID_FREQUENCY, |
761 | .default_value = 175250000L, | 875 | .default_value = 0, |
762 | .set_value = ctrl_freq_set, | 876 | .set_value = ctrl_freq_set, |
763 | .get_value = ctrl_freq_get, | 877 | .get_value = ctrl_freq_get, |
764 | .is_dirty = ctrl_freq_is_dirty, | 878 | .is_dirty = ctrl_freq_is_dirty, |
765 | .clear_dirty = ctrl_freq_clear_dirty, | 879 | .clear_dirty = ctrl_freq_clear_dirty, |
766 | DEFINT(MIN_FREQ,MAX_FREQ), | 880 | DEFINT(0,0), |
881 | /* Hook in check for input value (tv/radio) and adjust | ||
882 | max/min values accordingly */ | ||
883 | .get_max_value = ctrl_freq_max_get, | ||
884 | .get_min_value = ctrl_freq_min_get, | ||
767 | },{ | 885 | },{ |
768 | .desc = "Channel", | 886 | .desc = "Channel", |
769 | .name = "channel", | 887 | .name = "channel", |
@@ -775,7 +893,11 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
775 | .name = "freq_table_value", | 893 | .name = "freq_table_value", |
776 | .set_value = ctrl_channelfreq_set, | 894 | .set_value = ctrl_channelfreq_set, |
777 | .get_value = ctrl_channelfreq_get, | 895 | .get_value = ctrl_channelfreq_get, |
778 | DEFINT(MIN_FREQ,MAX_FREQ), | 896 | DEFINT(0,0), |
897 | /* Hook in check for input value (tv/radio) and adjust | ||
898 | max/min values accordingly */ | ||
899 | .get_max_value = ctrl_freq_max_get, | ||
900 | .get_min_value = ctrl_freq_min_get, | ||
779 | },{ | 901 | },{ |
780 | .desc = "Channel Program ID", | 902 | .desc = "Channel Program ID", |
781 | .name = "freq_table_channel", | 903 | .name = "freq_table_channel", |
@@ -796,7 +918,20 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
796 | .desc = "Signal Present", | 918 | .desc = "Signal Present", |
797 | .name = "signal_present", | 919 | .name = "signal_present", |
798 | .get_value = ctrl_signal_get, | 920 | .get_value = ctrl_signal_get, |
799 | DEFBOOL, | 921 | DEFINT(0,65535), |
922 | },{ | ||
923 | .desc = "Audio Modes Present", | ||
924 | .name = "audio_modes_present", | ||
925 | .get_value = ctrl_audio_modes_present_get, | ||
926 | /* For this type we "borrow" the V4L2_TUNER_MODE enum from | ||
927 | v4l. Nothing outside of this module cares about this, | ||
928 | but I reuse it in order to also reuse the | ||
929 | control_values_audiomode string table. */ | ||
930 | DEFMASK(((1 << V4L2_TUNER_MODE_MONO)| | ||
931 | (1 << V4L2_TUNER_MODE_STEREO)| | ||
932 | (1 << V4L2_TUNER_MODE_LANG1)| | ||
933 | (1 << V4L2_TUNER_MODE_LANG2)), | ||
934 | control_values_audiomode), | ||
800 | },{ | 935 | },{ |
801 | .desc = "Video Standards Available Mask", | 936 | .desc = "Video Standards Available Mask", |
802 | .name = "video_standard_mask_available", | 937 | .name = "video_standard_mask_available", |
@@ -846,7 +981,7 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
846 | } | 981 | } |
847 | }; | 982 | }; |
848 | 983 | ||
849 | #define CTRLDEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0])) | 984 | #define CTRLDEF_COUNT ARRAY_SIZE(control_defs) |
850 | 985 | ||
851 | 986 | ||
852 | const char *pvr2_config_get_name(enum pvr2_config cfg) | 987 | const char *pvr2_config_get_name(enum pvr2_config cfg) |
@@ -855,7 +990,8 @@ const char *pvr2_config_get_name(enum pvr2_config cfg) | |||
855 | case pvr2_config_empty: return "empty"; | 990 | case pvr2_config_empty: return "empty"; |
856 | case pvr2_config_mpeg: return "mpeg"; | 991 | case pvr2_config_mpeg: return "mpeg"; |
857 | case pvr2_config_vbi: return "vbi"; | 992 | case pvr2_config_vbi: return "vbi"; |
858 | case pvr2_config_radio: return "radio"; | 993 | case pvr2_config_pcm: return "pcm"; |
994 | case pvr2_config_rawvideo: return "raw video"; | ||
859 | } | 995 | } |
860 | return "<unknown>"; | 996 | return "<unknown>"; |
861 | } | 997 | } |
@@ -872,6 +1008,40 @@ unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw) | |||
872 | return hdw->serial_number; | 1008 | return hdw->serial_number; |
873 | } | 1009 | } |
874 | 1010 | ||
1011 | unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw) | ||
1012 | { | ||
1013 | return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio; | ||
1014 | } | ||
1015 | |||
1016 | /* Set the currently tuned frequency and account for all possible | ||
1017 | driver-core side effects of this action. */ | ||
1018 | void pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsigned long val) | ||
1019 | { | ||
1020 | if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { | ||
1021 | if (hdw->freqSelector) { | ||
1022 | /* Swing over to radio frequency selection */ | ||
1023 | hdw->freqSelector = 0; | ||
1024 | hdw->freqDirty = !0; | ||
1025 | } | ||
1026 | if (hdw->freqValRadio != val) { | ||
1027 | hdw->freqValRadio = val; | ||
1028 | hdw->freqSlotRadio = 0; | ||
1029 | hdw->freqDirty = !0; | ||
1030 | } | ||
1031 | } else { | ||
1032 | if (!(hdw->freqSelector)) { | ||
1033 | /* Swing over to television frequency selection */ | ||
1034 | hdw->freqSelector = 1; | ||
1035 | hdw->freqDirty = !0; | ||
1036 | } | ||
1037 | if (hdw->freqValTelevision != val) { | ||
1038 | hdw->freqValTelevision = val; | ||
1039 | hdw->freqSlotTelevision = 0; | ||
1040 | hdw->freqDirty = !0; | ||
1041 | } | ||
1042 | } | ||
1043 | } | ||
1044 | |||
875 | int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw) | 1045 | int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw) |
876 | { | 1046 | { |
877 | return hdw->unit_number; | 1047 | return hdw->unit_number; |
@@ -960,12 +1130,10 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) | |||
960 | }; | 1130 | }; |
961 | static const struct pvr2_string_table fw_file_defs[] = { | 1131 | static const struct pvr2_string_table fw_file_defs[] = { |
962 | [PVR2_HDW_TYPE_29XXX] = { | 1132 | [PVR2_HDW_TYPE_29XXX] = { |
963 | fw_files_29xxx, | 1133 | fw_files_29xxx, ARRAY_SIZE(fw_files_29xxx) |
964 | sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]), | ||
965 | }, | 1134 | }, |
966 | [PVR2_HDW_TYPE_24XXX] = { | 1135 | [PVR2_HDW_TYPE_24XXX] = { |
967 | fw_files_24xxx, | 1136 | fw_files_24xxx, ARRAY_SIZE(fw_files_24xxx) |
968 | sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]), | ||
969 | }, | 1137 | }, |
970 | }; | 1138 | }; |
971 | hdw->fw1_state = FW1_STATE_FAILED; // default result | 1139 | hdw->fw1_state = FW1_STATE_FAILED; // default result |
@@ -1041,7 +1209,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1041 | { | 1209 | { |
1042 | const struct firmware *fw_entry = NULL; | 1210 | const struct firmware *fw_entry = NULL; |
1043 | void *fw_ptr; | 1211 | void *fw_ptr; |
1044 | unsigned int pipe, fw_len, fw_done; | 1212 | unsigned int pipe, fw_len, fw_done, bcnt, icnt; |
1045 | int actual_length; | 1213 | int actual_length; |
1046 | int ret = 0; | 1214 | int ret = 0; |
1047 | int fwidx; | 1215 | int fwidx; |
@@ -1052,8 +1220,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1052 | trace_firmware("pvr2_upload_firmware2"); | 1220 | trace_firmware("pvr2_upload_firmware2"); |
1053 | 1221 | ||
1054 | ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder", | 1222 | ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder", |
1055 | sizeof(fw_files)/sizeof(fw_files[0]), | 1223 | ARRAY_SIZE(fw_files), fw_files); |
1056 | fw_files); | ||
1057 | if (ret < 0) return ret; | 1224 | if (ret < 0) return ret; |
1058 | fwidx = ret; | 1225 | fwidx = ret; |
1059 | ret = 0; | 1226 | ret = 0; |
@@ -1079,8 +1246,13 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1079 | ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/ | 1246 | ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/ |
1080 | ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/ | 1247 | ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/ |
1081 | ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/ | 1248 | ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/ |
1082 | ret |= pvr2_write_u8(hdw, 0x52, 0); | 1249 | LOCK_TAKE(hdw->ctl_lock); do { |
1083 | ret |= pvr2_write_u16(hdw, 0x0600, 0); | 1250 | hdw->cmd_buffer[0] = FX2CMD_FWPOST1; |
1251 | ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); | ||
1252 | hdw->cmd_buffer[0] = FX2CMD_MEMSEL; | ||
1253 | hdw->cmd_buffer[1] = 0; | ||
1254 | ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0); | ||
1255 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
1084 | 1256 | ||
1085 | if (ret) { | 1257 | if (ret) { |
1086 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 1258 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
@@ -1093,11 +1265,11 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1093 | 1265 | ||
1094 | fw_len = fw_entry->size; | 1266 | fw_len = fw_entry->size; |
1095 | 1267 | ||
1096 | if (fw_len % FIRMWARE_CHUNK_SIZE) { | 1268 | if (fw_len % sizeof(u32)) { |
1097 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 1269 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
1098 | "size of %s firmware" | 1270 | "size of %s firmware" |
1099 | " must be a multiple of 8192B", | 1271 | " must be a multiple of %u bytes", |
1100 | fw_files[fwidx]); | 1272 | fw_files[fwidx],sizeof(u32)); |
1101 | release_firmware(fw_entry); | 1273 | release_firmware(fw_entry); |
1102 | return -1; | 1274 | return -1; |
1103 | } | 1275 | } |
@@ -1112,18 +1284,21 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1112 | 1284 | ||
1113 | pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT); | 1285 | pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT); |
1114 | 1286 | ||
1115 | for (fw_done = 0 ; (fw_done < fw_len) && !ret ; | 1287 | fw_done = 0; |
1116 | fw_done += FIRMWARE_CHUNK_SIZE ) { | 1288 | for (fw_done = 0; fw_done < fw_len;) { |
1117 | int i; | 1289 | bcnt = fw_len - fw_done; |
1118 | memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE); | 1290 | if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE; |
1119 | /* Usbsnoop log shows that we must swap bytes... */ | 1291 | memcpy(fw_ptr, fw_entry->data + fw_done, bcnt); |
1120 | for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++) | 1292 | /* Usbsnoop log shows that we must swap bytes... */ |
1121 | ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]); | 1293 | for (icnt = 0; icnt < bcnt/4 ; icnt++) |
1122 | 1294 | ((u32 *)fw_ptr)[icnt] = | |
1123 | ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr, | 1295 | ___swab32(((u32 *)fw_ptr)[icnt]); |
1124 | FIRMWARE_CHUNK_SIZE, | 1296 | |
1297 | ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt, | ||
1125 | &actual_length, HZ); | 1298 | &actual_length, HZ); |
1126 | ret |= (actual_length != FIRMWARE_CHUNK_SIZE); | 1299 | ret |= (actual_length != bcnt); |
1300 | if (ret) break; | ||
1301 | fw_done += bcnt; | ||
1127 | } | 1302 | } |
1128 | 1303 | ||
1129 | trace_firmware("upload of %s : %i / %i ", | 1304 | trace_firmware("upload of %s : %i / %i ", |
@@ -1142,7 +1317,11 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1142 | 1317 | ||
1143 | ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/ | 1318 | ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/ |
1144 | ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/ | 1319 | ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/ |
1145 | ret |= pvr2_write_u16(hdw, 0x0600, 0); | 1320 | LOCK_TAKE(hdw->ctl_lock); do { |
1321 | hdw->cmd_buffer[0] = FX2CMD_MEMSEL; | ||
1322 | hdw->cmd_buffer[1] = 0; | ||
1323 | ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0); | ||
1324 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
1146 | 1325 | ||
1147 | if (ret) { | 1326 | if (ret) { |
1148 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 1327 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
@@ -1479,7 +1658,7 @@ static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw) | |||
1479 | firmware needs be loaded. */ | 1658 | firmware needs be loaded. */ |
1480 | int result; | 1659 | int result; |
1481 | LOCK_TAKE(hdw->ctl_lock); do { | 1660 | LOCK_TAKE(hdw->ctl_lock); do { |
1482 | hdw->cmd_buffer[0] = 0xeb; | 1661 | hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR; |
1483 | result = pvr2_send_request_ex(hdw,HZ*1,!0, | 1662 | result = pvr2_send_request_ex(hdw,HZ*1,!0, |
1484 | hdw->cmd_buffer,1, | 1663 | hdw->cmd_buffer,1, |
1485 | hdw->cmd_buffer,1); | 1664 | hdw->cmd_buffer,1); |
@@ -1611,6 +1790,16 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) | |||
1611 | cptr->info->set_value(cptr,~0,cptr->info->default_value); | 1790 | cptr->info->set_value(cptr,~0,cptr->info->default_value); |
1612 | } | 1791 | } |
1613 | 1792 | ||
1793 | /* Set up special default values for the television and radio | ||
1794 | frequencies here. It's not really important what these defaults | ||
1795 | are, but I set them to something usable in the Chicago area just | ||
1796 | to make driver testing a little easier. */ | ||
1797 | |||
1798 | /* US Broadcast channel 7 (175.25 MHz) */ | ||
1799 | hdw->freqValTelevision = 175250000L; | ||
1800 | /* 104.3 MHz, a usable FM station for my area */ | ||
1801 | hdw->freqValRadio = 104300000L; | ||
1802 | |||
1614 | // Do not use pvr2_reset_ctl_endpoints() here. It is not | 1803 | // Do not use pvr2_reset_ctl_endpoints() here. It is not |
1615 | // thread-safe against the normal pvr2_send_request() mechanism. | 1804 | // thread-safe against the normal pvr2_send_request() mechanism. |
1616 | // (We should make it thread safe). | 1805 | // (We should make it thread safe). |
@@ -1750,26 +1939,24 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1750 | struct pvr2_ctl_info *ciptr; | 1939 | struct pvr2_ctl_info *ciptr; |
1751 | 1940 | ||
1752 | hdw_type = devid - pvr2_device_table; | 1941 | hdw_type = devid - pvr2_device_table; |
1753 | if (hdw_type >= | 1942 | if (hdw_type >= ARRAY_SIZE(pvr2_device_names)) { |
1754 | sizeof(pvr2_device_names)/sizeof(pvr2_device_names[0])) { | ||
1755 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 1943 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
1756 | "Bogus device type of %u reported",hdw_type); | 1944 | "Bogus device type of %u reported",hdw_type); |
1757 | return NULL; | 1945 | return NULL; |
1758 | } | 1946 | } |
1759 | 1947 | ||
1760 | hdw = kmalloc(sizeof(*hdw),GFP_KERNEL); | 1948 | hdw = kzalloc(sizeof(*hdw),GFP_KERNEL); |
1761 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", | 1949 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", |
1762 | hdw,pvr2_device_names[hdw_type]); | 1950 | hdw,pvr2_device_names[hdw_type]); |
1763 | if (!hdw) goto fail; | 1951 | if (!hdw) goto fail; |
1764 | memset(hdw,0,sizeof(*hdw)); | 1952 | hdw->tuner_signal_stale = !0; |
1765 | cx2341x_fill_defaults(&hdw->enc_ctl_state); | 1953 | cx2341x_fill_defaults(&hdw->enc_ctl_state); |
1766 | 1954 | ||
1767 | hdw->control_cnt = CTRLDEF_COUNT; | 1955 | hdw->control_cnt = CTRLDEF_COUNT; |
1768 | hdw->control_cnt += MPEGDEF_COUNT; | 1956 | hdw->control_cnt += MPEGDEF_COUNT; |
1769 | hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt, | 1957 | hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt, |
1770 | GFP_KERNEL); | 1958 | GFP_KERNEL); |
1771 | if (!hdw->controls) goto fail; | 1959 | if (!hdw->controls) goto fail; |
1772 | memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * hdw->control_cnt); | ||
1773 | hdw->hdw_type = hdw_type; | 1960 | hdw->hdw_type = hdw_type; |
1774 | for (idx = 0; idx < hdw->control_cnt; idx++) { | 1961 | for (idx = 0; idx < hdw->control_cnt; idx++) { |
1775 | cptr = hdw->controls + idx; | 1962 | cptr = hdw->controls + idx; |
@@ -1783,11 +1970,9 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1783 | cptr->info = control_defs+idx; | 1970 | cptr->info = control_defs+idx; |
1784 | } | 1971 | } |
1785 | /* Define and configure additional controls from cx2341x module. */ | 1972 | /* Define and configure additional controls from cx2341x module. */ |
1786 | hdw->mpeg_ctrl_info = kmalloc( | 1973 | hdw->mpeg_ctrl_info = kzalloc( |
1787 | sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL); | 1974 | sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL); |
1788 | if (!hdw->mpeg_ctrl_info) goto fail; | 1975 | if (!hdw->mpeg_ctrl_info) goto fail; |
1789 | memset(hdw->mpeg_ctrl_info,0, | ||
1790 | sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT); | ||
1791 | for (idx = 0; idx < MPEGDEF_COUNT; idx++) { | 1976 | for (idx = 0; idx < MPEGDEF_COUNT; idx++) { |
1792 | cptr = hdw->controls + idx + CTRLDEF_COUNT; | 1977 | cptr = hdw->controls + idx + CTRLDEF_COUNT; |
1793 | ciptr = &(hdw->mpeg_ctrl_info[idx].info); | 1978 | ciptr = &(hdw->mpeg_ctrl_info[idx].info); |
@@ -1872,7 +2057,9 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1872 | 2057 | ||
1873 | hdw->eeprom_addr = -1; | 2058 | hdw->eeprom_addr = -1; |
1874 | hdw->unit_number = -1; | 2059 | hdw->unit_number = -1; |
1875 | hdw->v4l_minor_number = -1; | 2060 | hdw->v4l_minor_number_video = -1; |
2061 | hdw->v4l_minor_number_vbi = -1; | ||
2062 | hdw->v4l_minor_number_radio = -1; | ||
1876 | hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); | 2063 | hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); |
1877 | if (!hdw->ctl_write_buffer) goto fail; | 2064 | if (!hdw->ctl_write_buffer) goto fail; |
1878 | hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); | 2065 | hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); |
@@ -1929,10 +2116,10 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
1929 | if (hdw) { | 2116 | if (hdw) { |
1930 | usb_free_urb(hdw->ctl_read_urb); | 2117 | usb_free_urb(hdw->ctl_read_urb); |
1931 | usb_free_urb(hdw->ctl_write_urb); | 2118 | usb_free_urb(hdw->ctl_write_urb); |
1932 | if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer); | 2119 | kfree(hdw->ctl_read_buffer); |
1933 | if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer); | 2120 | kfree(hdw->ctl_write_buffer); |
1934 | if (hdw->controls) kfree(hdw->controls); | 2121 | kfree(hdw->controls); |
1935 | if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info); | 2122 | kfree(hdw->mpeg_ctrl_info); |
1936 | kfree(hdw); | 2123 | kfree(hdw); |
1937 | } | 2124 | } |
1938 | return NULL; | 2125 | return NULL; |
@@ -1982,9 +2169,6 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) | |||
1982 | pvr2_stream_destroy(hdw->vid_stream); | 2169 | pvr2_stream_destroy(hdw->vid_stream); |
1983 | hdw->vid_stream = NULL; | 2170 | hdw->vid_stream = NULL; |
1984 | } | 2171 | } |
1985 | if (hdw->audio_stat) { | ||
1986 | hdw->audio_stat->detach(hdw->audio_stat->ctxt); | ||
1987 | } | ||
1988 | if (hdw->decoder_ctrl) { | 2172 | if (hdw->decoder_ctrl) { |
1989 | hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt); | 2173 | hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt); |
1990 | } | 2174 | } |
@@ -1997,10 +2181,10 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) | |||
1997 | unit_pointers[hdw->unit_number] = NULL; | 2181 | unit_pointers[hdw->unit_number] = NULL; |
1998 | } | 2182 | } |
1999 | } while (0); up(&pvr2_unit_sem); | 2183 | } while (0); up(&pvr2_unit_sem); |
2000 | if (hdw->controls) kfree(hdw->controls); | 2184 | kfree(hdw->controls); |
2001 | if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info); | 2185 | kfree(hdw->mpeg_ctrl_info); |
2002 | if (hdw->std_defs) kfree(hdw->std_defs); | 2186 | kfree(hdw->std_defs); |
2003 | if (hdw->std_enum_names) kfree(hdw->std_enum_names); | 2187 | kfree(hdw->std_enum_names); |
2004 | kfree(hdw); | 2188 | kfree(hdw); |
2005 | } | 2189 | } |
2006 | 2190 | ||
@@ -2210,10 +2394,9 @@ static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) | |||
2210 | cptr = hdw->controls + idx; | 2394 | cptr = hdw->controls + idx; |
2211 | if (cptr->info->is_dirty == 0) continue; | 2395 | if (cptr->info->is_dirty == 0) continue; |
2212 | if (!cptr->info->is_dirty(cptr)) continue; | 2396 | if (!cptr->info->is_dirty(cptr)) continue; |
2213 | if (!commit_flag) { | 2397 | commit_flag = !0; |
2214 | commit_flag = !0; | ||
2215 | } | ||
2216 | 2398 | ||
2399 | if (!(pvrusb2_debug & PVR2_TRACE_CTL)) continue; | ||
2217 | bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ", | 2400 | bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ", |
2218 | cptr->info->name); | 2401 | cptr->info->name); |
2219 | value = 0; | 2402 | value = 0; |
@@ -2263,6 +2446,13 @@ static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) | |||
2263 | stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); | 2446 | stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); |
2264 | } | 2447 | } |
2265 | 2448 | ||
2449 | if (hdw->input_dirty) { | ||
2450 | /* pk: If input changes to or from radio, then the encoder | ||
2451 | needs to be restarted (for ENC_MUTE_VIDEO to work) */ | ||
2452 | stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN); | ||
2453 | } | ||
2454 | |||
2455 | |||
2266 | if (hdw->srate_dirty) { | 2456 | if (hdw->srate_dirty) { |
2267 | /* Write new sample rate into control structure since | 2457 | /* Write new sample rate into control structure since |
2268 | * the master copy is stale. We must track srate | 2458 | * the master copy is stale. We must track srate |
@@ -2343,39 +2533,11 @@ const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) | |||
2343 | } | 2533 | } |
2344 | 2534 | ||
2345 | 2535 | ||
2346 | /* Return bit mask indicating signal status */ | ||
2347 | static unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw) | ||
2348 | { | ||
2349 | unsigned int msk = 0; | ||
2350 | switch (hdw->input_val) { | ||
2351 | case PVR2_CVAL_INPUT_TV: | ||
2352 | case PVR2_CVAL_INPUT_RADIO: | ||
2353 | if (hdw->decoder_ctrl && | ||
2354 | hdw->decoder_ctrl->tuned(hdw->decoder_ctrl->ctxt)) { | ||
2355 | msk |= PVR2_SIGNAL_OK; | ||
2356 | if (hdw->audio_stat && | ||
2357 | hdw->audio_stat->status(hdw->audio_stat->ctxt)) { | ||
2358 | if (hdw->flag_stereo) { | ||
2359 | msk |= PVR2_SIGNAL_STEREO; | ||
2360 | } | ||
2361 | if (hdw->flag_bilingual) { | ||
2362 | msk |= PVR2_SIGNAL_SAP; | ||
2363 | } | ||
2364 | } | ||
2365 | } | ||
2366 | break; | ||
2367 | default: | ||
2368 | msk |= PVR2_SIGNAL_OK | PVR2_SIGNAL_STEREO; | ||
2369 | } | ||
2370 | return msk; | ||
2371 | } | ||
2372 | |||
2373 | |||
2374 | int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw) | 2536 | int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw) |
2375 | { | 2537 | { |
2376 | int result; | 2538 | int result; |
2377 | LOCK_TAKE(hdw->ctl_lock); do { | 2539 | LOCK_TAKE(hdw->ctl_lock); do { |
2378 | hdw->cmd_buffer[0] = 0x0b; | 2540 | hdw->cmd_buffer[0] = FX2CMD_GET_USB_SPEED; |
2379 | result = pvr2_send_request(hdw, | 2541 | result = pvr2_send_request(hdw, |
2380 | hdw->cmd_buffer,1, | 2542 | hdw->cmd_buffer,1, |
2381 | hdw->cmd_buffer,1); | 2543 | hdw->cmd_buffer,1); |
@@ -2386,14 +2548,25 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw) | |||
2386 | } | 2548 | } |
2387 | 2549 | ||
2388 | 2550 | ||
2389 | /* Return bit mask indicating signal status */ | 2551 | /* Execute poll of tuner status */ |
2390 | unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw) | 2552 | void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw) |
2391 | { | 2553 | { |
2392 | unsigned int msk = 0; | ||
2393 | LOCK_TAKE(hdw->big_lock); do { | 2554 | LOCK_TAKE(hdw->big_lock); do { |
2394 | msk = pvr2_hdw_get_signal_status_internal(hdw); | 2555 | pvr2_i2c_core_status_poll(hdw); |
2395 | } while (0); LOCK_GIVE(hdw->big_lock); | 2556 | } while (0); LOCK_GIVE(hdw->big_lock); |
2396 | return msk; | 2557 | } |
2558 | |||
2559 | |||
2560 | /* Return information about the tuner */ | ||
2561 | int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp) | ||
2562 | { | ||
2563 | LOCK_TAKE(hdw->big_lock); do { | ||
2564 | if (hdw->tuner_signal_stale) { | ||
2565 | pvr2_i2c_core_status_poll(hdw); | ||
2566 | } | ||
2567 | memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner)); | ||
2568 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2569 | return 0; | ||
2397 | } | 2570 | } |
2398 | 2571 | ||
2399 | 2572 | ||
@@ -2442,14 +2615,12 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag) | |||
2442 | pvr2_trace(PVR2_TRACE_FIRMWARE, | 2615 | pvr2_trace(PVR2_TRACE_FIRMWARE, |
2443 | "Preparing to suck out CPU firmware"); | 2616 | "Preparing to suck out CPU firmware"); |
2444 | hdw->fw_size = 0x2000; | 2617 | hdw->fw_size = 0x2000; |
2445 | hdw->fw_buffer = kmalloc(hdw->fw_size,GFP_KERNEL); | 2618 | hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL); |
2446 | if (!hdw->fw_buffer) { | 2619 | if (!hdw->fw_buffer) { |
2447 | hdw->fw_size = 0; | 2620 | hdw->fw_size = 0; |
2448 | break; | 2621 | break; |
2449 | } | 2622 | } |
2450 | 2623 | ||
2451 | memset(hdw->fw_buffer,0,hdw->fw_size); | ||
2452 | |||
2453 | /* We have to hold the CPU during firmware upload. */ | 2624 | /* We have to hold the CPU during firmware upload. */ |
2454 | pvr2_hdw_cpureset_assert(hdw,1); | 2625 | pvr2_hdw_cpureset_assert(hdw,1); |
2455 | 2626 | ||
@@ -2513,16 +2684,28 @@ int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs, | |||
2513 | } | 2684 | } |
2514 | 2685 | ||
2515 | 2686 | ||
2516 | int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw) | 2687 | int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw, |
2688 | enum pvr2_v4l_type index) | ||
2517 | { | 2689 | { |
2518 | return hdw->v4l_minor_number; | 2690 | switch (index) { |
2691 | case pvr2_v4l_type_video: return hdw->v4l_minor_number_video; | ||
2692 | case pvr2_v4l_type_vbi: return hdw->v4l_minor_number_vbi; | ||
2693 | case pvr2_v4l_type_radio: return hdw->v4l_minor_number_radio; | ||
2694 | default: return -1; | ||
2695 | } | ||
2519 | } | 2696 | } |
2520 | 2697 | ||
2521 | 2698 | ||
2522 | /* Store the v4l minor device number */ | 2699 | /* Store a v4l minor device number */ |
2523 | void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,int v) | 2700 | void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw, |
2701 | enum pvr2_v4l_type index,int v) | ||
2524 | { | 2702 | { |
2525 | hdw->v4l_minor_number = v; | 2703 | switch (index) { |
2704 | case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v; | ||
2705 | case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v; | ||
2706 | case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v; | ||
2707 | default: break; | ||
2708 | } | ||
2526 | } | 2709 | } |
2527 | 2710 | ||
2528 | 2711 | ||
@@ -2804,7 +2987,7 @@ int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data) | |||
2804 | 2987 | ||
2805 | LOCK_TAKE(hdw->ctl_lock); | 2988 | LOCK_TAKE(hdw->ctl_lock); |
2806 | 2989 | ||
2807 | hdw->cmd_buffer[0] = 0x04; /* write register prefix */ | 2990 | hdw->cmd_buffer[0] = FX2CMD_REG_WRITE; /* write register prefix */ |
2808 | PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data); | 2991 | PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data); |
2809 | hdw->cmd_buffer[5] = 0; | 2992 | hdw->cmd_buffer[5] = 0; |
2810 | hdw->cmd_buffer[6] = (reg >> 8) & 0xff; | 2993 | hdw->cmd_buffer[6] = (reg >> 8) & 0xff; |
@@ -2825,7 +3008,7 @@ static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data) | |||
2825 | 3008 | ||
2826 | LOCK_TAKE(hdw->ctl_lock); | 3009 | LOCK_TAKE(hdw->ctl_lock); |
2827 | 3010 | ||
2828 | hdw->cmd_buffer[0] = 0x05; /* read register prefix */ | 3011 | hdw->cmd_buffer[0] = FX2CMD_REG_READ; /* read register prefix */ |
2829 | hdw->cmd_buffer[1] = 0; | 3012 | hdw->cmd_buffer[1] = 0; |
2830 | hdw->cmd_buffer[2] = 0; | 3013 | hdw->cmd_buffer[2] = 0; |
2831 | hdw->cmd_buffer[3] = 0; | 3014 | hdw->cmd_buffer[3] = 0; |
@@ -2843,39 +3026,6 @@ static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data) | |||
2843 | } | 3026 | } |
2844 | 3027 | ||
2845 | 3028 | ||
2846 | static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res) | ||
2847 | { | ||
2848 | int ret; | ||
2849 | |||
2850 | LOCK_TAKE(hdw->ctl_lock); | ||
2851 | |||
2852 | hdw->cmd_buffer[0] = (data >> 8) & 0xff; | ||
2853 | hdw->cmd_buffer[1] = data & 0xff; | ||
2854 | |||
2855 | ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res); | ||
2856 | |||
2857 | LOCK_GIVE(hdw->ctl_lock); | ||
2858 | |||
2859 | return ret; | ||
2860 | } | ||
2861 | |||
2862 | |||
2863 | static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res) | ||
2864 | { | ||
2865 | int ret; | ||
2866 | |||
2867 | LOCK_TAKE(hdw->ctl_lock); | ||
2868 | |||
2869 | hdw->cmd_buffer[0] = data; | ||
2870 | |||
2871 | ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res); | ||
2872 | |||
2873 | LOCK_GIVE(hdw->ctl_lock); | ||
2874 | |||
2875 | return ret; | ||
2876 | } | ||
2877 | |||
2878 | |||
2879 | static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw) | 3029 | static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw) |
2880 | { | 3030 | { |
2881 | if (!hdw->flag_ok) return; | 3031 | if (!hdw->flag_ok) return; |
@@ -2949,7 +3099,7 @@ int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) | |||
2949 | LOCK_TAKE(hdw->ctl_lock); do { | 3099 | LOCK_TAKE(hdw->ctl_lock); do { |
2950 | pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset"); | 3100 | pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset"); |
2951 | hdw->flag_ok = !0; | 3101 | hdw->flag_ok = !0; |
2952 | hdw->cmd_buffer[0] = 0xdd; | 3102 | hdw->cmd_buffer[0] = FX2CMD_DEEP_RESET; |
2953 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); | 3103 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); |
2954 | } while (0); LOCK_GIVE(hdw->ctl_lock); | 3104 | } while (0); LOCK_GIVE(hdw->ctl_lock); |
2955 | return status; | 3105 | return status; |
@@ -2961,7 +3111,7 @@ int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) | |||
2961 | int status; | 3111 | int status; |
2962 | LOCK_TAKE(hdw->ctl_lock); do { | 3112 | LOCK_TAKE(hdw->ctl_lock); do { |
2963 | pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup"); | 3113 | pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup"); |
2964 | hdw->cmd_buffer[0] = 0xde; | 3114 | hdw->cmd_buffer[0] = FX2CMD_POWER_ON; |
2965 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); | 3115 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); |
2966 | } while (0); LOCK_GIVE(hdw->ctl_lock); | 3116 | } while (0); LOCK_GIVE(hdw->ctl_lock); |
2967 | return status; | 3117 | return status; |
@@ -2994,7 +3144,8 @@ static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) | |||
2994 | { | 3144 | { |
2995 | int status; | 3145 | int status; |
2996 | LOCK_TAKE(hdw->ctl_lock); do { | 3146 | LOCK_TAKE(hdw->ctl_lock); do { |
2997 | hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37); | 3147 | hdw->cmd_buffer[0] = |
3148 | (runFl ? FX2CMD_STREAMING_ON : FX2CMD_STREAMING_OFF); | ||
2998 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); | 3149 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); |
2999 | } while (0); LOCK_GIVE(hdw->ctl_lock); | 3150 | } while (0); LOCK_GIVE(hdw->ctl_lock); |
3000 | if (!status) { | 3151 | if (!status) { |
@@ -3093,7 +3244,7 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) | |||
3093 | { | 3244 | { |
3094 | int result; | 3245 | int result; |
3095 | LOCK_TAKE(hdw->ctl_lock); do { | 3246 | LOCK_TAKE(hdw->ctl_lock); do { |
3096 | hdw->cmd_buffer[0] = 0xeb; | 3247 | hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR; |
3097 | result = pvr2_send_request(hdw, | 3248 | result = pvr2_send_request(hdw, |
3098 | hdw->cmd_buffer,1, | 3249 | hdw->cmd_buffer,1, |
3099 | hdw->cmd_buffer,1); | 3250 | hdw->cmd_buffer,1); |
@@ -3105,7 +3256,7 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) | |||
3105 | 3256 | ||
3106 | 3257 | ||
3107 | int pvr2_hdw_register_access(struct pvr2_hdw *hdw, | 3258 | int pvr2_hdw_register_access(struct pvr2_hdw *hdw, |
3108 | u32 chip_id,unsigned long reg_id, | 3259 | u32 chip_id, u64 reg_id, |
3109 | int setFl,u32 *val_ptr) | 3260 | int setFl,u32 *val_ptr) |
3110 | { | 3261 | { |
3111 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 3262 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
@@ -3115,6 +3266,8 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw, | |||
3115 | int stat = 0; | 3266 | int stat = 0; |
3116 | int okFl = 0; | 3267 | int okFl = 0; |
3117 | 3268 | ||
3269 | if (!capable(CAP_SYS_ADMIN)) return -EPERM; | ||
3270 | |||
3118 | req.i2c_id = chip_id; | 3271 | req.i2c_id = chip_id; |
3119 | req.reg = reg_id; | 3272 | req.reg = reg_id; |
3120 | if (setFl) req.val = *val_ptr; | 3273 | if (setFl) req.val = *val_ptr; |
@@ -3123,8 +3276,8 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw, | |||
3123 | cp = list_entry(item,struct pvr2_i2c_client,list); | 3276 | cp = list_entry(item,struct pvr2_i2c_client,list); |
3124 | if (cp->client->driver->id != chip_id) continue; | 3277 | if (cp->client->driver->id != chip_id) continue; |
3125 | stat = pvr2_i2c_client_cmd( | 3278 | stat = pvr2_i2c_client_cmd( |
3126 | cp,(setFl ? VIDIOC_INT_S_REGISTER : | 3279 | cp,(setFl ? VIDIOC_DBG_S_REGISTER : |
3127 | VIDIOC_INT_G_REGISTER),&req); | 3280 | VIDIOC_DBG_G_REGISTER),&req); |
3128 | if (!setFl) *val_ptr = req.val; | 3281 | if (!setFl) *val_ptr = req.val; |
3129 | okFl = !0; | 3282 | okFl = !0; |
3130 | break; | 3283 | break; |