diff options
Diffstat (limited to 'linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c')
-rw-r--r-- | linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 1764 |
1 files changed, 760 insertions, 1004 deletions
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index f0de1e154..890aa4a06 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -24,9 +24,9 @@ #include <linux/string.h> #include <linux/slab.h> #include <linux/firmware.h> -#include <linux/videodev2.h> #include <asm/semaphore.h> #include "pvrusb2.h" +#include "pvrusb2-std.h" #include "pvrusb2-util.h" #include "pvrusb2-hdw.h" #include "pvrusb2-i2c-core.h" @@ -53,6 +53,42 @@ static const char *pvr2_device_names[] = { #endif }; +struct pvr2_string_table { + const char **lst; + unsigned int cnt; +}; + +#ifdef CONFIG_VIDEO_PVRUSB2_24XXX +// Names of other client modules to request for 24xxx model hardware +static const char *pvr2_client_24xxx[] = { + "cx25840", + "tuner", + "tda9887", + "wm8775", +}; +#endif + +// Names of other client modules to request for 29xxx model hardware +static const char *pvr2_client_29xxx[] = { + "msp3400", + "saa7115", + "tuner", + "tda9887", +}; + +static struct pvr2_string_table pvr2_client_lists[] = { + [PVR2_HDW_TYPE_29XXX] = { + pvr2_client_29xxx, + sizeof(pvr2_client_29xxx)/sizeof(pvr2_client_29xxx[0]), + }, +#ifdef CONFIG_VIDEO_PVRUSB2_24XXX + [PVR2_HDW_TYPE_24XXX] = { + pvr2_client_24xxx, + sizeof(pvr2_client_24xxx)/sizeof(pvr2_client_24xxx[0]), + }, +#endif +}; + static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = 0}; DECLARE_MUTEX(pvr2_unit_sem); @@ -61,6 +97,7 @@ static int initusbreset = 1; static int procreload = 0; static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 }; static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; +static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; static int init_pause_msec = 0; module_param(ctlchg, int, S_IRUGO|S_IWUSR); @@ -74,6 +111,8 @@ MODULE_PARM_DESC(procreload, "Attempt init failure recovery with firmware reload"); module_param_array(tuner, int, NULL, 0444); MODULE_PARM_DESC(tuner,"specify installed tuner type"); +module_param_array(video_std, int, NULL, 0444); +MODULE_PARM_DESC(video_std,"specify initial video standard"); module_param_array(tolerance, int, NULL, 0444); MODULE_PARM_DESC(tolerance,"specify stream error tolerance"); @@ -123,39 +162,6 @@ static const char *control_values_audioemphasis[] = { }; -static const char *control_values_videostandard[] = { - "PAL-B", - "PAL-B1", - "PAL-G", - "PAL-H", - - "PAL-I", - "PAL-D", - "PAL-D1", - "PAL-K", - - "PAL-M", - "PAL-N", - "PAL-Nc", - "PAL-60", - - "NTSC-M", - "NTSC-M-JP", - "NTSC-443", - 0, - - "SECAM-B", - "SECAM-D", - "SECAM-G", - "SECAM-H", - - "SECAM-K", - "SECAM-K1", - "SECAM-L", - "SECAM-LC", -}; - - static const char *control_values_input[] = { [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/ [PVR2_CVAL_INPUT_RADIO] = "radio", @@ -180,339 +186,552 @@ static const char *control_values_hsm[] = { }; -#define VDEF(x) \ - .value_defs_ptr = x, \ - .value_defs_count = (sizeof(x)/sizeof(x[0])) - -static int pvr2_ctl_set_chanprog_id(struct pvr2_ctrl *cptr,int value); -static int pvr2_ctl_get_chanprog_id(struct pvr2_ctrl *cptr); -static int pvr2_ctl_get_signal(struct pvr2_ctrl *cptr); -static int pvr2_ctl_get_streaming(struct pvr2_ctrl *cptr); -static int pvr2_ctl_get_hsm(struct pvr2_ctrl *cptr); -static int pvr2_ctl_get_subsys_mask(struct pvr2_ctrl *cptr); -static int pvr2_ctl_set_subsys_mask(struct pvr2_ctrl *cptr,int val); -static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_ctrl *cptr); -static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_ctrl *cptr,int val); -static int pvr2_ctl_set_stdcur(struct pvr2_ctrl *cptr,int val); -static int pvr2_ctl_get_stdcur(struct pvr2_ctrl *cptr); -static int pvr2_ctl_get_stdavail(struct pvr2_ctrl *cptr); -static int pvr2_ctl_set_stdenumcur(struct pvr2_ctrl *cptr,int val); -static int pvr2_ctl_get_stdenumcur(struct pvr2_ctrl *cptr); - -static struct pvr2_ctl_def control_defs[] = -{ - [PVR2_CID_BRIGHTNESS] = { - .id = V4L2_CID_BRIGHTNESS, - .is_valid = !0, +static const char *control_values_subsystem[] = { + [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware", + [PVR2_SUBSYS_B_ENC_CFG] = "enc_config", + [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run", + [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run", + [PVR2_SUBSYS_B_ENC_RUN] = "enc_run", +}; + + +static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp) +{ + struct pvr2_hdw *hdw = cptr->hdw; + if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) { + *vp = hdw->freqTable[hdw->freqProgSlot-1]; + } else { + *vp = 0; + } + return 0; +} + +static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v) +{ + struct pvr2_hdw *hdw = cptr->hdw; + if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) { + hdw->freqTable[hdw->freqProgSlot-1] = v; + } + return 0; +} + +static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp) +{ + *vp = cptr->hdw->freqProgSlot; + return 0; +} + +static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v) +{ + struct pvr2_hdw *hdw = cptr->hdw; + if ((v >= 0) && (v <= FREQTABLE_SIZE)) { + hdw->freqProgSlot = v; + } + return 0; +} + +static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp) +{ + *vp = cptr->hdw->freqSlot; + return 0; +} + +static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int v) +{ + unsigned freq = 0; + struct pvr2_hdw *hdw = cptr->hdw; + hdw->freqSlot = v; + if ((hdw->freqSlot > 0) && (hdw->freqSlot <= FREQTABLE_SIZE)) { + freq = hdw->freqTable[hdw->freqSlot-1]; + } + if (freq && (freq != hdw->freqVal)) { + hdw->freqVal = freq; + hdw->freqDirty = !0; + } + return 0; +} + +static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp) +{ + *vp = cptr->hdw->freqVal; + return 0; +} + +static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr) +{ + return cptr->hdw->freqDirty != 0; +} + +static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr) +{ + cptr->hdw->freqDirty = 0; +} + +static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v) +{ + struct pvr2_hdw *hdw = cptr->hdw; + hdw->freqVal = v; + hdw->freqDirty = !0; + hdw->freqSlot = 0; + return 0; +} + +static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp) +{ + *vp = cptr->hdw->flag_streaming_enabled; + return 0; +} + +static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp) +{ + int result = pvr2_hdw_is_hsm(cptr->hdw); + *vp = PVR2_CVAL_HSM_FULL; + if (result < 0) *vp = PVR2_CVAL_HSM_FAIL; + if (result) *vp = PVR2_CVAL_HSM_HIGH; + return 0; +} + +static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp) +{ + *vp = cptr->hdw->std_mask_avail; + return 0; +} + +static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v) +{ + struct pvr2_hdw *hdw = cptr->hdw; + v4l2_std_id ns; + ns = hdw->std_mask_avail; + ns = (ns & ~m) | (v & m); + if (ns == hdw->std_mask_avail) return 0; + hdw->std_mask_avail = ns; + pvr2_hdw_internal_set_std_avail(hdw); + pvr2_hdw_internal_find_stdenum(hdw); + return 0; +} + +static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val, + char *bufPtr,unsigned int bufSize, + unsigned int *len) +{ + *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val); + return 0; +} + +static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr, + const char *bufPtr,unsigned int bufSize, + int *mskp,int *valp) +{ + int ret; + v4l2_std_id id; + ret = pvr2_std_str_to_id(&id,bufPtr,bufSize); + if (ret < 0) return ret; + if (mskp) *mskp = id; + if (valp) *valp = id; + return 0; +} + +static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp) +{ + *vp = cptr->hdw->std_mask_cur; + return 0; +} + +static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v) +{ + struct pvr2_hdw *hdw = cptr->hdw; + v4l2_std_id ns; + ns = hdw->std_mask_cur; + ns = (ns & ~m) | (v & m); + if (ns == hdw->std_mask_cur) return 0; + hdw->std_mask_cur = ns; + hdw->std_dirty = !0; + pvr2_hdw_internal_find_stdenum(hdw); + return 0; +} + +static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr) +{ + return cptr->hdw->std_dirty != 0; +} + +static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr) +{ + cptr->hdw->std_dirty = 0; +} + +static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp) +{ + *vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) & + PVR2_SIGNAL_OK) ? 1 : 0); + return 0; +} + +static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp) +{ + *vp = cptr->hdw->subsys_enabled_mask; + return 0; +} + +static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v) +{ + pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v); + return 0; +} + +static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp) +{ + *vp = cptr->hdw->subsys_stream_mask; + return 0; +} + +static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v) +{ + pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v); + return 0; +} + +static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v) +{ + struct pvr2_hdw *hdw = cptr->hdw; + if (v < 0) return -EINVAL; + if (v > hdw->std_enum_cnt) return -EINVAL; + hdw->std_enum_cur = v; + if (!v) return 0; + v--; + if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0; + hdw->std_mask_cur = hdw->std_defs[v].id; + hdw->std_dirty = !0; + return 0; +} + + +static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp) +{ + *vp = cptr->hdw->std_enum_cur; + return 0; +} + + +static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr) +{ + return cptr->hdw->std_dirty != 0; +} + + +static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr) +{ + cptr->hdw->std_dirty = 0; +} + + +#define DEFINT(vmin,vmax) \ + .type = pvr2_ctl_int, \ + .def.type_int.min_value = vmin, \ + .def.type_int.max_value = vmax + +#define DEFENUM(tab) \ + .type = pvr2_ctl_enum, \ + .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \ + .def.type_enum.value_names = tab + +#define DEFMASK(msk,tab) \ + .type = pvr2_ctl_bitmask, \ + .def.type_bitmask.valid_bits = msk, \ + .def.type_bitmask.bit_names = tab + +#define DEFREF(vname) \ + .set_value = ctrl_set_##vname, \ + .get_value = ctrl_get_##vname, \ + .is_dirty = ctrl_isdirty_##vname, \ + .clear_dirty = ctrl_cleardirty_##vname + + +#define VCREATE_FUNCS(vname) \ +static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \ +{*vp = cptr->hdw->vname##_val; return 0;} \ +static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \ +{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \ +static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \ +{return cptr->hdw->vname##_dirty != 0;} \ +static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \ +{cptr->hdw->vname##_dirty = 0;} + +VCREATE_FUNCS(brightness) +VCREATE_FUNCS(contrast) +VCREATE_FUNCS(saturation) +VCREATE_FUNCS(hue) +VCREATE_FUNCS(volume) +VCREATE_FUNCS(balance) +VCREATE_FUNCS(bass) +VCREATE_FUNCS(treble) +VCREATE_FUNCS(mute) +VCREATE_FUNCS(srate) +VCREATE_FUNCS(audiobitrate) +VCREATE_FUNCS(audiocrc) +VCREATE_FUNCS(audioemphasis) +VCREATE_FUNCS(vbr) +VCREATE_FUNCS(videobitrate) +VCREATE_FUNCS(videopeak) +VCREATE_FUNCS(input) +VCREATE_FUNCS(audiomode) +VCREATE_FUNCS(res_hor) +VCREATE_FUNCS(res_ver) +VCREATE_FUNCS(interlace) +VCREATE_FUNCS(audiolayer) + +#define MIN_FREQ 55250000L +#define MAX_FREQ 850000000L + +/* Table definition of all controls which can be manipulated */ +static const struct pvr2_ctl_info control_defs[] = { + { + .v4l_id = V4L2_CID_BRIGHTNESS, .desc = "Brightness", .name = "brightness", - .min_value = 0, - .max_value = 255, .default_value = 128, - }, - [PVR2_CID_CONTRAST] = { - .id = V4L2_CID_CONTRAST, - .is_valid = !0, + DEFREF(brightness), + DEFINT(0,255), + },{ + .v4l_id = V4L2_CID_CONTRAST, .desc = "Contrast", .name = "contrast", - .min_value = 0, - .max_value = 127, .default_value = 68, - }, - [PVR2_CID_SATURATION] = { - .id = V4L2_CID_SATURATION, - .is_valid = !0, + DEFREF(contrast), + DEFINT(0,127), + },{ + .v4l_id = V4L2_CID_SATURATION, .desc = "Saturation", .name = "saturation", - .min_value = 0, - .max_value = 127, .default_value = 64, - }, - [PVR2_CID_HUE] = { - .id = V4L2_CID_HUE, - .is_valid = !0, + DEFREF(saturation), + DEFINT(0,127), + },{ + .v4l_id = V4L2_CID_HUE, .desc = "Hue", .name = "hue", - .min_value = -128, - .max_value = 127, .default_value = 0, - }, - [PVR2_CID_VOLUME] = { - .id = V4L2_CID_AUDIO_VOLUME, - .is_valid = !0, + DEFREF(hue), + DEFINT(-128,127), + },{ + .v4l_id = V4L2_CID_AUDIO_VOLUME, .desc = "Volume", .name = "volume", - .min_value = 0, - .max_value = 65535, .default_value = 65535, - }, - [PVR2_CID_BALANCE] = { - .id = V4L2_CID_AUDIO_BALANCE, - .is_valid = !0, + DEFREF(volume), + DEFINT(0,65535), + },{ + .v4l_id = V4L2_CID_AUDIO_BALANCE, .desc = "Balance", .name = "balance", - .min_value = -32768, - .max_value = 32767, .default_value = 0, - }, - [PVR2_CID_BASS] = { - .id = V4L2_CID_AUDIO_BASS, - .is_valid = !0, + DEFREF(balance), + DEFINT(-32768,32767), + },{ + .v4l_id = V4L2_CID_AUDIO_BASS, .desc = "Bass", .name = "bass", - .min_value = -32768, - .max_value = 32767, .default_value = 0, - }, - [PVR2_CID_TREBLE] = { - .id = V4L2_CID_AUDIO_TREBLE, - .is_valid = !0, + DEFREF(bass), + DEFINT(-32768,32767), + },{ + .v4l_id = V4L2_CID_AUDIO_TREBLE, .desc = "Treble", .name = "treble", - .min_value = -32768, - .max_value = 32767, .default_value = 0, - }, - [PVR2_CID_MUTE] = { - .id = V4L2_CID_AUDIO_MUTE, - .is_valid = !0, + DEFREF(treble), + DEFINT(-32768,32767), + },{ + .v4l_id = V4L2_CID_AUDIO_MUTE, .desc = "Mute", .name = "mute", - .min_value = 0, - .max_value = 1, .default_value = 0, - }, - [PVR2_CID_SRATE] = { - .id = V4L2_CID_PVR_SRATE, - .is_valid = !0, + DEFREF(mute), + DEFINT(0,1), + },{ + .v4l_id = V4L2_CID_PVR_SRATE, .desc = "Sample rate", .name = "srate", - .min_value = PVR2_CVAL_SRATE_MIN, - .max_value = PVR2_CVAL_SRATE_MAX, .default_value = PVR2_CVAL_SRATE_48, - VDEF(control_values_srate), - }, - [PVR2_CID_AUDIOBITRATE] = { - .id = V4L2_CID_PVR_AUDIOBITRATE, - .is_valid = !0, + DEFREF(srate), + DEFENUM(control_values_srate), + },{ + .v4l_id = V4L2_CID_PVR_AUDIOBITRATE, .desc = "Audio Bitrate", .name = "audio_bitrate", - .min_value = PVR2_CVAL_AUDIOBITRATE_MIN, - .max_value = PVR2_CVAL_AUDIOBITRATE_MAX, .default_value = PVR2_CVAL_AUDIOBITRATE_224, - VDEF(control_values_audiobitrate), - }, - [PVR2_CID_AUDIOCRC] = { - .id = V4L2_CID_PVR_AUDIOCRC, - .is_valid = !0, + DEFREF(audiobitrate), + DEFENUM(control_values_audiobitrate), + },{ + .v4l_id = V4L2_CID_PVR_AUDIOCRC, .desc = "Audio CRC", .name = "audio_crc", - .min_value = 0, - .max_value = 1, .default_value = 1, - }, - [PVR2_CID_AUDIOEMPHASIS] = { - .id = V4L2_CID_PVR_AUDIOEMPHASIS, - .is_valid = !0, + DEFREF(audiocrc), + DEFINT(0,1), + },{ + .desc = "Audio Layer", + .name = "audio_layer", + .default_value = 2, + DEFREF(audiolayer), + DEFINT(0,3), + },{ + .v4l_id = V4L2_CID_PVR_AUDIOEMPHASIS, .desc = "Audio Emphasis", .name = "audio_emphasis", - .min_value = PVR2_CVAL_AUDIOEMPHASIS_MIN, - .max_value = PVR2_CVAL_AUDIOEMPHASIS_MAX, .default_value = PVR2_CVAL_AUDIOEMPHASIS_NONE, - VDEF(control_values_audioemphasis), - }, - [PVR2_CID_VBR] = { - .id = V4L2_CID_PVR_VBR, - .is_valid = !0, + DEFREF(audioemphasis), + DEFENUM(control_values_audioemphasis), + },{ + .desc = "Interlace mode", + .name = "interlace", + .internal_id = PVR2_CID_INTERLACE, + .default_value = 0, + DEFREF(interlace), + DEFINT(0,1), + },{ + .v4l_id = V4L2_CID_PVR_VBR, .desc = "Variable video bitrate", .name = "vbr", - .min_value = 0, - .max_value = 1, .default_value = 0, - }, - [PVR2_CID_AVERAGEVIDEOBITRATE] = { - .id = V4L2_CID_PVR_VIDEOBITRATE, - .is_valid = !0, + DEFREF(vbr), + DEFINT(0,1), + },{ + .v4l_id = V4L2_CID_PVR_VIDEOBITRATE, .desc = "Average video bitrate", .name = "video_average_bitrate", - .min_value = 1, - .max_value = 20000000, .default_value = 6000000, - }, - [PVR2_CID_PEAKVIDEOBITRATE] = { - .id = V4L2_CID_PVR_VIDEOPEAK, - .is_valid = !0, + DEFREF(videobitrate), + DEFINT(500000,20000000), + },{ + .v4l_id = V4L2_CID_PVR_VIDEOPEAK, .desc = "Peak video bitrate", .name = "video_peak_bitrate", - .min_value = 1, - .max_value = 20000000, .default_value = 6000000, - }, - [PVR2_CID_STDAVAIL] = { - .is_valid = !0, - .desc = "Video Standards Available Mask", - .name = "video_standard_mask_available", - .min_value = 0, - .max_value = 0, - .default_value = (int)V4L2_STD_UNKNOWN, - .mask_value = (int)V4L2_STD_ALL, - .get_func = pvr2_ctl_get_stdavail, - VDEF(control_values_videostandard), - }, - [PVR2_CID_INPUT] = { - .id = V4L2_CID_PVR_INPUT, - .is_valid = !0, + DEFREF(videopeak), + DEFINT(500000,20000000), + },{ .desc = "Video Source", .name = "input", - .min_value = PVR2_CVAL_INPUT_MIN, - .max_value = PVR2_CVAL_INPUT_MAX, + .internal_id = PVR2_CID_INPUT, .default_value = PVR2_CVAL_INPUT_TV, - VDEF(control_values_input), - }, - [PVR2_CID_AUDIOMODE] = { - .id = V4L2_CID_PVR_AUDIOMODE, - .is_valid = !0, + DEFREF(input), + DEFENUM(control_values_input), + },{ .desc = "Audio Mode", .name = "audio_mode", - .min_value = V4L2_TUNER_MODE_MONO, - .max_value = V4L2_TUNER_MODE_LANG1_LANG2, + .internal_id = PVR2_CID_AUDIOMODE, .default_value = V4L2_TUNER_MODE_STEREO, - VDEF(control_values_audiomode), - }, - [PVR2_CID_FREQUENCY] = { - .id = V4L2_CID_PVR_FREQUENCY, - .is_valid = !0, + DEFREF(audiomode), + DEFENUM(control_values_audiomode), + },{ .desc = "Tuner Frequency (Hz)", .name = "frequency", - .min_value = 55250000L, - .max_value = 850000000L, + .internal_id = PVR2_CID_FREQUENCY, .default_value = 175250000L, - }, - [PVR2_CID_HRES] = { - .id = V4L2_CID_PVR_HRES, - .is_valid = !0, + .set_value = ctrl_freq_set, + .get_value = ctrl_freq_get, + .is_dirty = ctrl_freq_is_dirty, + .clear_dirty = ctrl_freq_clear_dirty, + DEFINT(MIN_FREQ,MAX_FREQ), + },{ + .desc = "Channel", + .name = "channel", + .set_value = ctrl_channel_set, + .get_value = ctrl_channel_get, + DEFINT(0,FREQTABLE_SIZE), + },{ + .desc = "Channel Program Frequency", + .name = "freq_table_value", + .set_value = ctrl_channelfreq_set, + .get_value = ctrl_channelfreq_get, + DEFINT(MIN_FREQ,MAX_FREQ), + },{ + .desc = "Channel Program ID", + .name = "freq_table_channel", + .set_value = ctrl_channelprog_set, + .get_value = ctrl_channelprog_get, + DEFINT(0,FREQTABLE_SIZE), + },{ .desc = "Horizontal capture resolution", .name = "resolution_hor", - .min_value = 320, - .max_value = 720, + .internal_id = PVR2_CID_HRES, .default_value = 720, - }, - [PVR2_CID_VRES] = { - .id = V4L2_CID_PVR_VRES, - .is_valid = !0, + DEFREF(res_hor), + DEFINT(320,720), + },{ .desc = "Vertical capture resolution", .name = "resolution_ver", - .min_value = 200, - .max_value = 625, + .internal_id = PVR2_CID_VRES, .default_value = 480, - }, - [PVR2_CID_INTERLACE] = { - .id = V4L2_CID_PVR_INTERLACE, - .is_valid = !0, - .desc = "Interlace mode", - .name = "interlace", - .min_value = 0, - .max_value = 1, - .default_value = 0, - }, - [PVR2_CID_AUDIOLAYER] = { - .is_valid = !0, - .desc = "Audio Layer", - .name = "audio_layer", - .min_value = 0, /* This is all a wild guess */ - .max_value = 3, - .default_value = 2, /* Appears to be all that is supported */ - }, - [PVR2_CID_CHANNEL] = { - .is_valid = !0, - .desc = "Channel", - .name = "channel", - .min_value = 0, - .max_value = FREQTABLE_SIZE, - .default_value = 0, - }, - [PVR2_CID_CHANPROG_ID] = { - .is_valid = !0, - .desc = "Channel Program ID", - .name = "freq_table_channel", - .min_value = 0, - .max_value = FREQTABLE_SIZE, - .default_value = 0, - }, - [PVR2_CID_CHANPROG_FREQ] = { - .is_valid = !0, - .desc = "Channel Program Frequency", - .name = "freq_table_value", - .min_value = 55250000L, - .max_value = 850000000L, - .skip_init = !0, - .set_func = pvr2_ctl_set_chanprog_id, - .get_func = pvr2_ctl_get_chanprog_id, - }, - [PVR2_CID_SIGNAL_PRESENT] = { - .is_valid = !0, - .desc = "Signal Present", - .name = "signal_present", - .min_value = 0, - .max_value = 1, - .get_func = pvr2_ctl_get_signal, - }, - [PVR2_CID_STREAMING_ENABLED] = { - .is_valid = !0, + DEFREF(res_ver), + DEFINT(200,625), + },{ .desc = "Streaming Enabled", .name = "streaming_enabled", - .min_value = 0, - .max_value = 1, - .get_func = pvr2_ctl_get_streaming, - }, - [PVR2_CID_HSM] = { - .is_valid = !0, + .get_value = ctrl_streamingenabled_get, + DEFINT(0,1), + },{ .desc = "USB Speed", .name = "usb_speed", - .min_value = PVR2_CVAL_HSM_MIN, - .max_value = PVR2_CVAL_HSM_MAX, - .get_func = pvr2_ctl_get_hsm, - VDEF(control_values_hsm), - }, - [PVR2_CID_SUBSYS_MASK] = { - .is_valid = !0, + .get_value = ctrl_hsm_get, + DEFENUM(control_values_hsm), + },{ + .desc = "Signal Present", + .name = "signal_present", + .get_value = ctrl_signal_get, + DEFINT(0,1), + },{ + .desc = "Video Standards Available Mask", + .name = "video_standard_mask_available", + .internal_id = PVR2_CID_STDAVAIL, + .skip_init = !0, + .get_value = ctrl_stdavail_get, + .set_value = ctrl_stdavail_set, + .val_to_sym = ctrl_std_val_to_sym, + .sym_to_val = ctrl_std_sym_to_val, + .type = pvr2_ctl_bitmask, + },{ + .desc = "Video Standards In Use Mask", + .name = "video_standard_mask_active", + .internal_id = PVR2_CID_STDCUR, + .skip_init = !0, + .get_value = ctrl_stdcur_get, + .set_value = ctrl_stdcur_set, + .is_dirty = ctrl_stdcur_is_dirty, + .clear_dirty = ctrl_stdcur_clear_dirty, + .val_to_sym = ctrl_std_val_to_sym, + .sym_to_val = ctrl_std_sym_to_val, + .type = pvr2_ctl_bitmask, + },{ .desc = "Subsystem enabled mask", .name = "debug_subsys_mask", - .min_value = 0, - .max_value = 0x7fffffff, .skip_init = !0, - .get_func = pvr2_ctl_get_subsys_mask, - .set_func = pvr2_ctl_set_subsys_mask, - }, - [PVR2_CID_SUBSYS_STREAM_MASK] = { - .is_valid = !0, + .get_value = ctrl_subsys_get, + .set_value = ctrl_subsys_set, + DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem), + },{ .desc = "Subsystem stream mask", .name = "debug_subsys_stream_mask", - .min_value = 0, - .max_value = 0x7fffffff, .skip_init = !0, - .get_func = pvr2_ctl_get_subsys_stream_mask, - .set_func = pvr2_ctl_set_subsys_stream_mask, - }, - [PVR2_CID_STDCUR] = { - .id = V4L2_CID_PVR_STDCUR, - .is_valid = !0, - .desc = "Video Standard In Use Mask", - .name = "video_standard_mask_active", - .min_value = 0, - .max_value = 0, - .default_value = (int)V4L2_STD_UNKNOWN, - .mask_value = (int)V4L2_STD_ALL, - .set_func = pvr2_ctl_set_stdcur, - .get_func = pvr2_ctl_get_stdcur, - VDEF(control_values_videostandard), - }, + .get_value = ctrl_subsys_stream_get, + .set_value = ctrl_subsys_stream_set, + DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem), + },{ + .desc = "Video Standard Name", + .name = "video_standard", + .internal_id = PVR2_CID_STDENUM, + .skip_init = !0, + .get_value = ctrl_stdenumcur_get, + .set_value = ctrl_stdenumcur_set, + .is_dirty = ctrl_stdenumcur_is_dirty, + .clear_dirty = ctrl_stdenumcur_clear_dirty, + .type = pvr2_ctl_enum, + } }; -#undef VDEF +#define CTRL_COUNT (sizeof(control_defs)/sizeof(control_defs[0])) -#define CTRL_DEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0])) -#define CTRL_COUNT CTRL_DEF_COUNT+1 const char *pvr2_config_get_name(enum pvr2_config cfg) { @@ -634,10 +853,7 @@ int pvr2_upload_firmware1(struct pvr2_hdw *hdw) "v4l-pvrusb2-24xxx-01.fw", }; #endif - static const struct { - const char **lst; - unsigned int cnt; - } fw_file_defs[] = { + static const struct pvr2_string_table fw_file_defs[] = { [PVR2_HDW_TYPE_29XXX] = { fw_files_29xxx, sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]), @@ -825,17 +1041,17 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) pvr2_trace(PVR2_TRACE_ERROR_LEGS, "firmware2 upload post-proc failure"); } else { - hdw->subsys_enabled_mask |= PVR2_SUBSYS_ENC_FIRMWARE; + hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE); } return ret; } #define FIRMWARE_RECOVERY_BITS \ - (PVR2_SUBSYS_ENC_CFG | \ - PVR2_SUBSYS_ENC_RUN | \ - PVR2_SUBSYS_ENC_FIRMWARE | \ - PVR2_SUBSYS_USBSTREAM_RUN) + ((1<<PVR2_SUBSYS_B_ENC_CFG) | \ + (1<<PVR2_SUBSYS_B_ENC_RUN) | \ + (1<<PVR2_SUBSYS_B_ENC_FIRMWARE) | \ + (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) /* @@ -903,7 +1119,7 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, vmsk = (nmsk ^ hdw->subsys_enabled_mask) & hdw->subsys_enabled_mask; if (vmsk) { - if (vmsk & PVR2_SUBSYS_ENC_RUN) { + if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " pvr2_encoder_stop"); @@ -916,13 +1132,13 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, continue; } } - if (vmsk & PVR2_SUBSYS_USBSTREAM_RUN) { + if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " pvr2_hdw_cmd_usbstream(0)"); pvr2_hdw_cmd_usbstream(hdw,0); } - if (vmsk & PVR2_SUBSYS_DIGITIZER_RUN) { + if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " decoder disable"); @@ -935,7 +1151,7 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, " No decoder present"); } hdw->subsys_enabled_mask &= - ~PVR2_SUBSYS_DIGITIZER_RUN; + ~(1<<PVR2_SUBSYS_B_DIGITIZER_RUN); } if (vmsk & PVR2_SUBSYS_CFG_ALL) { hdw->subsys_enabled_mask &= @@ -944,7 +1160,7 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, } vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk; if (vmsk) { - if (vmsk & PVR2_SUBSYS_ENC_FIRMWARE) { + if (vmsk & (1<<PVR2_SUBSYS_B_ENC_FIRMWARE)) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " pvr2_upload_firmware2"); @@ -957,7 +1173,7 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, break; } } - if (vmsk & PVR2_SUBSYS_ENC_CFG) { + if (vmsk & (1<<PVR2_SUBSYS_B_ENC_CFG)) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " pvr2_encoder_configure"); @@ -970,7 +1186,7 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, continue; } } - if (vmsk & PVR2_SUBSYS_DIGITIZER_RUN) { + if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " decoder enable"); @@ -983,15 +1199,15 @@ void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, " No decoder present"); } hdw->subsys_enabled_mask |= - PVR2_SUBSYS_DIGITIZER_RUN; + (1<<PVR2_SUBSYS_B_DIGITIZER_RUN); } - if (vmsk & PVR2_SUBSYS_USBSTREAM_RUN) { + if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " pvr2_hdw_cmd_usbstream(1)"); pvr2_hdw_cmd_usbstream(hdw,!0); } - if (vmsk & PVR2_SUBSYS_ENC_RUN) { + if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) { pvr2_trace(PVR2_TRACE_CTL, "/*---TRACE_CTL----*/" " pvr2_encoder_start"); @@ -1066,12 +1282,6 @@ void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw, } -static int pvr2_ctl_get_streaming(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->flag_streaming_enabled != 0; -} - - int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl) { if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0; @@ -1142,6 +1352,17 @@ static int get_default_tuner_type(struct pvr2_hdw *hdw) } +static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw) +{ + int unit_number = hdw->unit_number; + int tp = 0; + if ((unit_number >= 0) && (unit_number < PVR_NUM)) { + tp = video_std[unit_number]; + } + return tp; +} + + static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw) { int unit_number = hdw->unit_number; @@ -1178,6 +1399,59 @@ static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw) return result == 0; } +static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) +{ + char buf[40]; + unsigned int bcnt; + v4l2_std_id std1,std2; + + std1 = get_default_standard(hdw); + + bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom); + pvr2_trace(PVR2_TRACE_INIT, + "Supported video standard(s) reported by eeprom: %.*s", + bcnt,buf); + + hdw->std_mask_avail = hdw->std_mask_eeprom; + + std2 = std1 & ~hdw->std_mask_avail; + if (std2) { + bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2); + pvr2_trace(PVR2_TRACE_INIT, + "Expanding supported video standards" + " to include: %.*s", + bcnt,buf); + hdw->std_mask_avail |= std2; + } + + pvr2_hdw_internal_set_std_avail(hdw); + + if (std1) { + bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1); + pvr2_trace(PVR2_TRACE_INIT, + "Initial video standard forced to %.*s", + bcnt,buf); + hdw->std_mask_cur = std1; + hdw->std_dirty = !0; + pvr2_hdw_internal_find_stdenum(hdw); + return; + } + + if (hdw->std_enum_cnt > 1) { + // Autoselect the first listed standard + hdw->std_enum_cur = 1; + hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id; + hdw->std_dirty = !0; + pvr2_trace(PVR2_TRACE_INIT, + "Initial video standard auto-selected to %s", + hdw->std_defs[hdw->std_enum_cur-1].name); + return; + } + + pvr2_trace(PVR2_TRACE_EEPROM, + "Unable to select a viable initial video standard"); +} + static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) { @@ -1216,6 +1490,10 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) } if (!pvr2_hdw_dev_ok(hdw)) return; + for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) { + request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]); + } + pvr2_hdw_cmd_powerup(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; @@ -1231,10 +1509,9 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) for (idx = 0; idx < CTRL_COUNT; idx++) { cptr = hdw->controls + idx; - if (!pvr2_ctrl_is_valid(cptr)) continue; - if (cptr->ctl_def->skip_init) continue; - pvr2_ctrl_internal_set_value(cptr, - cptr->ctl_def->default_value); + if (cptr->info->skip_init) continue; + if (!cptr->info->set_value) continue; + cptr->info->set_value(cptr,~0,cptr->info->default_value); } // Do not use pvr2_reset_ctl_endpoints() here. It is not @@ -1252,6 +1529,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) if (!pvr2_hdw_dev_ok(hdw)) return; } + pvr2_hdw_setup_std(hdw); + if (!get_default_tuner_type(hdw)) { pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_setup: Tuner type overridden to %d", @@ -1264,23 +1543,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) if (!pvr2_hdw_dev_ok(hdw)) return; - for (idx = 0; idx < hdw->std_cnt; idx++) { - pvr2_trace(PVR2_TRACE_EEPROM, - "Detected video standard %s (from eeprom)", - hdw->std_defs[idx].name); - } - if (hdw->std_cnt) { - pvr2_trace(PVR2_TRACE_EEPROM, - "Initial video standard set to %s" - " (detected from eeprom)", - hdw->std_defs[hdw->std_id].name); - } else { - pvr2_trace(PVR2_TRACE_EEPROM, - "Unable to select a viable video standard"); - } - - if (!pvr2_hdw_dev_ok(hdw)) return; - pvr2_hdw_commit_ctl_internal(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; @@ -1384,6 +1646,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, unsigned int idx,cnt1,cnt2; struct pvr2_hdw *hdw; unsigned int hdw_type; + int valid_std_mask; + struct pvr2_ctrl *cptr; __u8 ifnum; hdw_type = devid - pvr2_device_table; @@ -1400,33 +1664,60 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, if (!hdw) goto fail; memset(hdw,0,sizeof(*hdw)); - // Initialize video standard enum dynamic control - hdw->video_std_enum.name = "video_standard"; - hdw->video_std_enum.desc = "Video Standard Name"; - hdw->video_std_enum.id = 0; // ????? - hdw->video_std_enum.set_func = pvr2_ctl_set_stdenumcur; - hdw->video_std_enum.get_func = pvr2_ctl_get_stdenumcur; - hdw->video_std_enum.mask_value = 0; - hdw->video_std_enum.max_value = 0; - hdw->video_std_enum.min_value = 0; - hdw->video_std_enum.default_value = 0; - hdw->video_std_enum.is_valid = !0; - hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * CTRL_COUNT, GFP_KERNEL); if (!hdw->controls) goto fail; memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * CTRL_COUNT); hdw->hdw_type = hdw_type; - for (idx = 0; idx < CTRL_DEF_COUNT; idx++) { - hdw->controls[idx].hdw = hdw; - hdw->controls[idx].ctl_def = control_defs + idx; - hdw->controls[idx].is_valid = - hdw->controls[idx].ctl_def->is_valid; + for (idx = 0; idx < 32; idx++) { + hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx]; + } + + for (idx = 0; idx < CTRL_COUNT; idx++) { + cptr = hdw->controls + idx; + cptr->hdw = hdw; + cptr->info = control_defs+idx; + } + + // Initialize video standard enum dynamic control + cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM); + if (cptr) { + memcpy(&hdw->std_info_enum,cptr->info, + sizeof(hdw->std_info_enum)); + cptr->info = &hdw->std_info_enum; + + } + // Initialize control data regarding video standard masks + valid_std_mask = pvr2_std_get_usable(); + for (idx = 0; idx < 32; idx++) { + if (!(valid_std_mask & (1 << idx))) continue; + cnt1 = pvr2_std_id_to_str( + hdw->std_mask_names[idx], + sizeof(hdw->std_mask_names[idx])-1, + 1 << idx); + hdw->std_mask_names[idx][cnt1] = 0; + } + cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL); + if (cptr) { + memcpy(&hdw->std_info_avail,cptr->info, + sizeof(hdw->std_info_avail)); + cptr->info = &hdw->std_info_avail; + hdw->std_info_avail.def.type_bitmask.bit_names = + hdw->std_mask_ptrs; + hdw->std_info_avail.def.type_bitmask.valid_bits = + valid_std_mask; + } + cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR); + if (cptr) { + memcpy(&hdw->std_info_cur,cptr->info, + sizeof(hdw->std_info_cur)); + cptr->info = &hdw->std_info_cur; + hdw->std_info_cur.def.type_bitmask.bit_names = + hdw->std_mask_ptrs; + hdw->std_info_avail.def.type_bitmask.valid_bits = + valid_std_mask; } - hdw->controls[PVR2_CID_STDNAME].hdw = hdw; - hdw->controls[PVR2_CID_STDNAME].ctl_def = &hdw->video_std_enum; - hdw->controls[PVR2_CID_STDNAME].is_valid = !0; hdw->eeprom_addr = -1; hdw->unit_number = -1; @@ -1468,7 +1759,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, /* Initialize the mask of subsystems that we will shut down when we stop streaming. */ hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL; - hdw->subsys_stream_mask |= PVR2_SUBSYS_ENC_CFG; + hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx", hdw->subsys_stream_mask); @@ -1556,7 +1847,7 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) } while (0); up(&pvr2_unit_sem); kfree(hdw->controls); if (hdw->std_defs) kfree(hdw->std_defs); - if (hdw->video_std_names) kfree(hdw->video_std_names); + if (hdw->std_enum_names) kfree(hdw->std_enum_names); kfree(hdw); } @@ -1585,363 +1876,75 @@ void pvr2_hdw_disconnect(struct pvr2_hdw *hdw) } -static int pvr2_ctl_set_chanprog_id(struct pvr2_ctrl *cptr,int value) -{ - /* This is a special case; the value to store is to an array, and - the element to select is determined by PVR_CID_CHANPROG_ID. */ - struct pvr2_hdw *hdw = cptr->hdw; - int id = hdw->controls[PVR2_CID_CHANPROG_ID].value; - if ((id < 1) || (id > FREQTABLE_SIZE)) return 0; - hdw->freqTable[id-1] = value; - if (hdw->controls[PVR2_CID_CHANNEL].value == id) { - /* If the current channel happens to be the slot we just - set, then act like the current channel just got changed - so we'll update that too. */ - hdw->controls[PVR2_CID_CHANNEL].dirty = !0; - } - return 0; -} - - -static int pvr2_ctl_get_chanprog_id(struct pvr2_ctrl *cptr) +// Attempt to autoselect an appropriate value for std_enum_cur given +// whatever is currently in std_mask_cur +void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw) { - /* This is a special case; the value to return is from an array, - and the element to select is determined by - PVR_CID_CHANPROG_ID. */ - struct pvr2_hdw *hdw = cptr->hdw; - int id = hdw->controls[PVR2_CID_CHANPROG_ID].value; - if ((id < 1) || (id > FREQTABLE_SIZE)) return 0; - return hdw->freqTable[id-1]; -} - -// Template data for possible enumerated video standards -static struct v4l2_standard pvr_standards[] = { - { - .id = V4L2_STD_PAL_BG, - .frameperiod = - { - .numerator = 1, - .denominator= 25 - }, - .framelines = 625, - .reserved = {0,0,0,0} - }, { - .id = V4L2_STD_PAL_I, - .frameperiod = - { - .numerator = 1, - .denominator= 25 - }, - .framelines = 625, - .reserved = {0,0,0,0} - }, { - .id = V4L2_STD_PAL_DK, - .frameperiod = - { - .numerator = 1, - .denominator= 25 - }, - .framelines = 625, - .reserved = {0,0,0,0} - }, { - .id = V4L2_STD_SECAM, - .frameperiod = - { - .numerator = 1, - .denominator= 25 - }, - .framelines = 625, - .reserved = {0,0,0,0} - }, { - .id = V4L2_STD_NTSC_M, - .frameperiod = - { - .numerator = 1001, - .denominator= 30000 - }, - .framelines = 525, - .reserved = {0,0,0,0} - }, { - .id = V4L2_STD_PAL_M, - .frameperiod = - { - .numerator = 1001, - .denominator= 30000 - }, - .framelines = 525, - .reserved = {0,0,0,0} - } -}; - -#define pvr_standards_cnt (sizeof(pvr_standards)/sizeof(pvr_standards[0])) - - -struct name_data { - struct v4l2_standard *std; - unsigned int bcnt; - unsigned int scnt; -}; - -static void name_build(struct name_data *dp,const char *str) -{ - if (!dp->bcnt) { - dp->bcnt = scnprintf(dp->std->name, - sizeof(dp->std->name)-1,"%s",str); - dp->scnt = 0; - return; - } - - dp->bcnt += scnprintf(dp->std->name+dp->bcnt, - sizeof(dp->std->name)-(1+dp->bcnt), - "%s%s", - (dp->scnt ? "/" : "-"),str); - (dp->scnt)++; -} - -// Generate a descriptive name for a given standard -static void name_bucket(struct v4l2_standard *std) -{ - struct name_data nd; - nd.std = std; - nd.bcnt = 0; - if (std->id & (V4L2_STD_PAL_B| - V4L2_STD_PAL_B1| - V4L2_STD_PAL_G| - V4L2_STD_PAL_H| - V4L2_STD_PAL_I| - V4L2_STD_PAL_D| - V4L2_STD_PAL_D1| - V4L2_STD_PAL_K)) { - name_build(&nd,"PAL"); - if (std->id & V4L2_STD_PAL_B) name_build(&nd,"B"); - if (std->id & V4L2_STD_PAL_B1) name_build(&nd,"B1"); - if (std->id & V4L2_STD_PAL_D) name_build(&nd,"D"); - if (std->id & V4L2_STD_PAL_D1) name_build(&nd,"D1"); - if (std->id & V4L2_STD_PAL_G) name_build(&nd,"G"); - if (std->id & V4L2_STD_PAL_H) name_build(&nd,"H"); - if (std->id & V4L2_STD_PAL_I) name_build(&nd,"I"); - if (std->id & V4L2_STD_PAL_K) name_build(&nd,"K"); - if (std->id & V4L2_STD_PAL_M) name_build(&nd,"M"); - if (std->id & V4L2_STD_PAL_N) name_build(&nd,"N"); - if (std->id & V4L2_STD_PAL_Nc) name_build(&nd,"Nc"); - if (std->id & V4L2_STD_PAL_60) name_build(&nd,"60"); - std->name[nd.bcnt] = 0; - return; - } - if (std->id & (V4L2_STD_NTSC_M| - V4L2_STD_NTSC_M_JP| - V4L2_STD_NTSC_443)) { - name_build(&nd,"NTSC"); - if (std->id & V4L2_STD_NTSC_M) name_build(&nd,"M"); - if (std->id & V4L2_STD_NTSC_M_JP) name_build(&nd,"Mjp"); - if (std->id & V4L2_STD_NTSC_443) name_build(&nd,"443"); - std->name[nd.bcnt] = 0; - return; - } - if (std->id & (V4L2_STD_SECAM_B| - V4L2_STD_SECAM_D| - V4L2_STD_SECAM_G| - V4L2_STD_SECAM_H| - V4L2_STD_SECAM_K| - V4L2_STD_SECAM_K1| - V4L2_STD_SECAM_L| - V4L2_STD_SECAM_LC)) { - name_build(&nd,"SECAM"); - if (std->id & V4L2_STD_SECAM_B) name_build(&nd,"B"); - if (std->id & V4L2_STD_SECAM_D) name_build(&nd,"D"); - if (std->id & V4L2_STD_SECAM_G) name_build(&nd,"G"); - if (std->id & V4L2_STD_SECAM_H) name_build(&nd,"H"); - if (std->id & V4L2_STD_SECAM_K) name_build(&nd,"K"); - if (std->id & V4L2_STD_SECAM_K1) name_build(&nd,"K1"); - if (std->id & V4L2_STD_SECAM_L) name_build(&nd,"L"); - if (std->id & V4L2_STD_SECAM_LC) name_build(&nd,"LC"); - std->name[nd.bcnt] = 0; - return; + unsigned int idx; + for (idx = 1; idx < hdw->std_enum_cnt; idx++) { + if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) { + hdw->std_enum_cur = idx; + return; + } } - std->name[0] = 0; + hdw->std_enum_cur = 0; } -// Given a mask of viable video standards to choose from, generate an -// appropriate array of v4l2_standard data that corresponds to it and set -// up related state in the driver to match. -void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw,int arg) +// Calculate correct set of enumerated standards based on currently known +// set of available standards bits. +void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw) { - v4l2_std_id buckets[pvr_standards_cnt]; - unsigned int idx1,idx2,std_cnt; - v4l2_std_id mmsk,amsk; - - amsk = (v4l2_std_id)arg; - - // Figure out which standard groups we can work with - std_cnt = 0; - mmsk = 0; - for (idx1 = 0; idx1 < pvr_standards_cnt; idx1++) { - buckets[idx1] = pvr_standards[idx1].id & amsk; - if (!buckets[idx1]) continue; - mmsk |= buckets[idx1]; - amsk &= ~buckets[idx1]; - std_cnt++; - } + struct v4l2_standard *newstd; + unsigned int std_cnt; + unsigned int idx; - if (amsk) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Failed to bucketize the following standards: 0x%llx", - amsk); - } + newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail); if (hdw->std_defs) { kfree(hdw->std_defs); hdw->std_defs = 0; } - if (hdw->video_std_names) { - kfree(hdw->video_std_names); - hdw->video_std_names = 0; + hdw->std_enum_cnt = 0; + if (hdw->std_enum_names) { + kfree(hdw->std_enum_names); + hdw->std_enum_names = 0; } - hdw->std_cnt = 0; if (!std_cnt) { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "Failed to identify any viable standard groups"); - hdw->video_std_avail = 0; - pvr2_hdw_internal_set_std_cur(hdw,0); - return; - } - - if (std_cnt) { - // Allocate new video standard array - hdw->std_defs = kmalloc(sizeof(struct v4l2_standard) * std_cnt, - GFP_KERNEL); - hdw->std_cnt = std_cnt; - memset(hdw->std_defs,0,sizeof(struct v4l2_standard) * std_cnt); - hdw->video_std_names = kmalloc(sizeof(char *) * std_cnt, - GFP_KERNEL); - memset(hdw->video_std_names,0,sizeof(char *) * std_cnt); - idx2 = 0; - - // Initialize video standard array - for (idx1 = 0; idx1 < pvr_standards_cnt; idx1++) { - if (!buckets[idx1]) continue; - memcpy(hdw->std_defs + idx2, - pvr_standards + idx1, - sizeof(struct v4l2_standard)); - hdw->std_defs[idx2].id = buckets[idx1]; - idx2++; - } - - // Generate a name for each known video standard - for (idx1 = 0; idx1 < std_cnt; idx1++) { - name_bucket(hdw->std_defs + idx1); - hdw->video_std_names[idx1] = - hdw->std_defs[idx1].name; - } - - // Set up the dynamic control for this standard - hdw->video_std_enum.value_defs_ptr = hdw->video_std_names; - hdw->video_std_enum.value_defs_count = std_cnt; - } - - hdw->video_std_avail = mmsk; - if (!(hdw->video_std_avail & hdw->video_std_cur)) { - // Reselect standard if there isn't one that matches... - pvr2_hdw_internal_set_stdenum_cur(hdw,0); - } -} - - -unsigned int pvr2_hdw_get_stdenum_count(struct pvr2_hdw *hdw) -{ - return hdw->std_cnt; -} - - -const struct v4l2_standard *pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw, - unsigned int idx) -{ - if (idx >= hdw->std_cnt) return 0; - return hdw->std_defs + idx; -} - - -int pvr2_hdw_internal_set_stdenum_cur(struct pvr2_hdw *hdw,int val) -{ - if (val < 0) return -EINVAL; - if (val >= hdw->std_cnt) return -EINVAL; - pvr2_hdw_internal_set_std_cur(hdw,hdw->std_defs[val].id); - return 0; -} - - -void pvr2_hdw_internal_set_std_cur(struct pvr2_hdw *hdw,int val) -{ - unsigned int idx; - v4l2_std_id msk,id; - - id = (v4l2_std_id)val; - // Only select from available standards - id &= hdw->video_std_avail; - - // Only select a single bit - for (idx = 0, msk = 1; msk; idx++, msk <<= 1) { - if (!(id & msk)) continue; - id = msk; - break; + "WARNING: Failed to identify any viable standards"); } - - // Get out if nothing found - if (!msk) return; - - // Fix up standard group now - hdw->video_std_cur = id; - hdw->controls[PVR2_CID_STDCUR].value = id; - hdw->controls[PVR2_CID_STDCUR].dirty = !0; - for (idx = 0; idx < hdw->std_cnt; idx++) { - if (hdw->std_defs[idx].id & id) { - hdw->std_id = idx; - return; - } + hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL); + hdw->std_enum_names[0] = "none"; + for (idx = 0; idx < std_cnt; idx++) { + hdw->std_enum_names[idx+1] = + newstd[idx].name; } - - // Should never really get here, but just in case... - hdw->std_id = 0; + // Set up the dynamic control for this standard + hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names; + hdw->std_info_enum.def.type_enum.count = std_cnt+1; + hdw->std_defs = newstd; + hdw->std_enum_cnt = std_cnt+1; + hdw->std_enum_cur = 0; + hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail; } -static int pvr2_ctl_set_stdcur(struct pvr2_ctrl *cptr,int val) +int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw, + struct v4l2_standard *std, + unsigned int idx) { - pvr2_hdw_internal_set_std_cur(cptr->hdw,val); - return 0; -} - - -static int pvr2_ctl_get_stdcur(struct pvr2_ctrl *cptr) -{ - return (int)(cptr->hdw->video_std_cur); -} - - -static int pvr2_ctl_set_stdenumcur(struct pvr2_ctrl *cptr,int val) -{ - if (val < 0) return -EINVAL; - if (val >= cptr->hdw->std_cnt) return -EINVAL; - cptr->hdw->std_id = val; - pvr2_hdw_internal_set_std_cur(cptr->hdw, - cptr->hdw->std_id); - return 0; -} - - -static int pvr2_ctl_get_stdenumcur(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->std_id; -} - - -static int pvr2_ctl_get_stdavail(struct pvr2_ctrl *cptr) -{ - return (int)(cptr->hdw->video_std_avail); + int ret = -EINVAL; + if (!idx) return ret; + LOCK_TAKE(hdw->big_lock); do { + if (idx >= hdw->std_enum_cnt) break; + idx--; + memcpy(std,hdw->std_defs+idx,sizeof(*std)); + ret = 0; + } while (0); LOCK_GIVE(hdw->big_lock); + return ret; } @@ -1956,14 +1959,14 @@ unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw) struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw, unsigned int idx) { - if (idx < 0) return 0; if (idx >= CTRL_COUNT) return 0; return hdw->controls + idx; } -/* Given an ID, retrieve the control structure associated with it. */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl(struct pvr2_hdw *hdw,unsigned int ctl_id) +/* Retrieve a control handle given its index (0..count-1) */ +struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw, + unsigned int ctl_id) { struct pvr2_ctrl *cptr; unsigned int idx; @@ -1972,212 +1975,38 @@ struct pvr2_ctrl *pvr2_hdw_get_ctrl(struct pvr2_hdw *hdw,unsigned int ctl_id) /* This could be made a lot more efficient, but for now... */ for (idx = 0; idx < CTRL_COUNT; idx++) { cptr = hdw->controls + idx; - i = cptr->ctl_def->id; + i = cptr->info->internal_id; if (i && (i == ctl_id)) return cptr; } - return 0; } -/* Set the current value of a given control. This assumes we are already - inside our critical region. */ -int pvr2_ctrl_internal_set_value(struct pvr2_ctrl *cptr,int value) -{ - const struct pvr2_ctl_def *dptr; - int ret; - if (!cptr) return -EINVAL; - if (!cptr->is_valid) return -EINVAL; - dptr = cptr->ctl_def; - if (!dptr->is_valid) return -EINVAL; - if (value < dptr->min_value) return -EINVAL; - if (value > dptr->max_value) return -EINVAL; - if (dptr->set_func) { - ret = dptr->set_func(cptr,value); - pvr2_i2c_core_check_stale(cptr->hdw); - pvr2_i2c_core_sync(cptr->hdw); - return ret; - } else if (dptr->get_func) { - /* If there's no "set" function yet there is still a "get" - function, then treat this as a read-only value. */ - return -EINVAL; - } - if ((cptr->value != value) || (ctlchg != 0)) { - cptr->value = value; - cptr->dirty = !0; - } - return 0; -} - - -/* Get the current value of a given control. This assumes that we are - already inside our critical region. */ -int pvr2_ctrl_internal_get_value(struct pvr2_ctrl *cptr) -{ - const struct pvr2_ctl_def *dptr; - if (!cptr) return 0; - if (!cptr->is_valid) return 0; - dptr = cptr->ctl_def; - if (!dptr->is_valid) return 0; - if (dptr->get_func) { - return dptr->get_func(cptr); - } - - return cptr->value; -} - - -/* Set the current value of the given control. */ -int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val) -{ - int ret; - if (!cptr) return -EINVAL; - LOCK_TAKE(cptr->hdw->big_lock); do { - ret = pvr2_ctrl_internal_set_value(cptr,val); - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Get the current value of the given control. */ -int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr) +/* Given an ID, retrieve the control structure associated with it. */ +struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id) { - int ret; - if (!cptr) return -EINVAL; - LOCK_TAKE(cptr->hdw->big_lock); do { - ret = pvr2_ctrl_internal_get_value(cptr); - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - + struct pvr2_ctrl *cptr; + unsigned int idx; + int i; -/* Return the type of the given control (int, enum, or bit mask). */ -int pvr2_ctrl_get_type(struct pvr2_ctrl *cptr) -{ - const struct pvr2_ctl_def *dptr; - if (!cptr) return PVR2_CTRL_TYPE_INVALID; - dptr = cptr->ctl_def; - if (dptr->mask_value) { - return PVR2_CTRL_TYPE_BITMASK; - } - if (dptr->value_defs_ptr) { - return PVR2_CTRL_TYPE_ENUM; + /* This could be made a lot more efficient, but for now... */ + for (idx = 0; idx < CTRL_COUNT; idx++) { + cptr = hdw->controls + idx; + i = cptr->info->v4l_id; + if (i && (i == ctl_id)) return cptr; } - return PVR2_CTRL_TYPE_INT; -} - - -/* Return the minimum legal value for a given control. This command is - only relevant for int or enum types. */ -int pvr2_ctrl_get_min_value(struct pvr2_ctrl *cptr) -{ - const struct pvr2_ctl_def *dptr; - if (!cptr) return 0; - dptr = cptr->ctl_def; - return dptr->min_value; -} - - -/* Return the maximum legal value for a given control. This command is - only relevant for int or enum types. */ -int pvr2_ctrl_get_max_value(struct pvr2_ctrl *cptr) -{ - const struct pvr2_ctl_def *dptr; - if (!cptr) return 0; - dptr = cptr->ctl_def; - return dptr->max_value; -} - - -/* Return the default value for a given control. */ -int pvr2_ctrl_get_default_value(struct pvr2_ctrl *cptr) -{ - const struct pvr2_ctl_def *dptr; - if (!cptr) return 0; - dptr = cptr->ctl_def; - return dptr->default_value; -} - - -/* Return a mask of which bits are used within the bit mask of a given - control. This command is only relevant for bit mask types. */ -int pvr2_ctrl_get_mask_value(struct pvr2_ctrl *cptr) -{ - const struct pvr2_ctl_def *dptr; - if (!cptr) return 0; - dptr = cptr->ctl_def; - return dptr->mask_value; -} - - -/* Return true if this is a valid control. */ -int pvr2_ctrl_is_valid(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - return cptr->is_valid; -} - - -/* Return true if the control can be set (otherwise it may only be read, - assuming that it is valid). */ -int pvr2_ctrl_is_writeable(struct pvr2_ctrl *cptr) -{ - const struct pvr2_ctl_def *dptr; - if (!cptr) return 0; - dptr = cptr->ctl_def; - if (!dptr->is_valid) return 0; - if (dptr->set_func) return !0; - if (dptr->get_func) return 0; - return !0; -} - - -/* Return the control's name, or null if there isn't a name or the control - isn't otherwise valid. */ -const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr) -{ - const struct pvr2_ctl_def *dptr; - if (!cptr) return 0; - dptr = cptr->ctl_def; - return dptr->name; -} - - -/* Return the control's description, or null if there isn't a name or the - control isn't otherwise valid. */ -const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr) -{ - const struct pvr2_ctl_def *dptr; - if (!cptr) return 0; - dptr = cptr->ctl_def; - return dptr->desc; + return 0; } -/* Return the name for an enumeration value or bit mask position for the - given control. If the control is not an enumeration or bit mask type, - then return null. */ -const char *pvr2_ctrl_get_value_name(struct pvr2_ctrl *cptr,int val) +static const char *get_ctrl_typename(enum pvr2_ctl_type tp) { - int msk,idx; - const struct pvr2_ctl_def *dptr; - if (!cptr) return 0; - dptr = cptr->ctl_def; - if (dptr->mask_value) { - for (idx = 0, msk = 1; - (idx < dptr->value_defs_count) && msk; - idx++, msk <<= 1) { - if (val & msk) { - return dptr->value_defs_ptr[idx]; - } - } - } else { - val -= dptr->min_value; - if (val < 0) return 0; - if (val >= dptr->value_defs_count) return 0; - return dptr->value_defs_ptr[val]; + switch (tp) { + case pvr2_ctl_int: return "integer"; + case pvr2_ctl_enum: return "enum"; + case pvr2_ctl_bitmask: return "bitmask"; } - return 0; + return ""; } @@ -2193,64 +2022,33 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) unsigned long saved_subsys_mask = hdw->subsys_enabled_mask; unsigned long stale_subsys_mask = 0; unsigned int idx; - const struct pvr2_ctl_def *dptr; struct pvr2_ctrl *cptr; int value; - const char *ctl_name; - const char *ctl_value; int commit_flag = 0; - - /* Let's see if the channel changed and we have to update the - frequency because of it. This setup means one can tune the - receiver either by just setting the channel (using the frequency - table), or by directly programming the frequency. How do we - resolve the obvious conflict here? The direct frequency takes - priority; if directly set then we commit that value and force - the channel to zero which is interpreted to mean "none". If on - the other hand we see that the channel has been set and it's a - legal value, then we copy that into the frequency. The metaphor - here is similar to when you tune your digital radio: You an - either set a frequency directly or punch up a pre-programmed - station. Either way a frequency is set, and if you do use a - preset, then the radio also shows you which preset it is - until - you override that by directly entering a new frequency. */ - if (hdw->controls[PVR2_CID_FREQUENCY].dirty) { - /* Frequency has been directly set, so clear out the - channel. */ - hdw->controls[PVR2_CID_CHANNEL].value = 0; - } else if (hdw->controls[PVR2_CID_CHANNEL].dirty) { - int id = hdw->controls[PVR2_CID_CHANNEL].value; - if ((id > 0) && (id <= FREQTABLE_SIZE)) { - if (hdw->controls[PVR2_CID_FREQUENCY].value != - hdw->freqTable[id-1]) { - hdw->controls[PVR2_CID_FREQUENCY].value = - hdw->freqTable[id-1]; - hdw->controls[PVR2_CID_FREQUENCY].dirty = !0; - } - } - } + char buf[100]; + unsigned int bcnt,ccnt; for (idx = 0; idx < CTRL_COUNT; idx++) { cptr = hdw->controls + idx; - if (!cptr->dirty) continue; + if (cptr->info->is_dirty == 0) continue; + if (!cptr->info->is_dirty(cptr)) continue; if (!commit_flag) { commit_flag = !0; } - value = cptr->value; - dptr = cptr->ctl_def; - ctl_name = dptr->name; - if (dptr->value_defs_ptr) { - if (value < dptr->value_defs_count) { - ctl_value = dptr->value_defs_ptr[value]; - } else { - ctl_value = "<out of range>"; - } - } else { - ctl_value = "<integer>"; - } + + bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ", + cptr->info->name); + value = 0; + cptr->info->get_value(cptr,&value); + pvr2_ctrl_value_to_sym_internal(cptr,~0,value, + buf+bcnt, + sizeof(buf)-bcnt,&ccnt); + bcnt += ccnt; + bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>", + get_ctrl_typename(cptr->info->type)); pvr2_trace(PVR2_TRACE_CTL, - "/*--TRACE_COMMIT--*/ \"%s\" <-- %d (%s)", - ctl_name,value,ctl_value); + "/*--TRACE_COMMIT--*/ %.*s", + bcnt,buf); } if (!commit_flag) { @@ -2261,40 +2059,40 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) /* When video standard changes, reset the hres and vres values - but if the user has pending changes there, then let the changes take priority. */ - if (hdw->controls[PVR2_CID_STDCUR].dirty) { + if (hdw->std_dirty) { /* Rewrite the vertical resolution to be appropriate to the video standard that has been selected. */ int nvres; - if (hdw->video_std_cur & V4L2_STD_525_60) { + if (hdw->std_mask_cur & V4L2_STD_525_60) { nvres = 480; } else { nvres = 576; } - if (nvres != hdw->controls[PVR2_CID_VRES].value) { - hdw->controls[PVR2_CID_VRES].value = nvres; - hdw->controls[PVR2_CID_VRES].dirty = !0; + if (nvres != hdw->res_ver_val) { + hdw->res_ver_val = nvres; + hdw->res_ver_dirty = !0; } - if (!hdw->controls[PVR2_CID_INTERLACE].value) { - hdw->controls[PVR2_CID_INTERLACE].value = 0; - hdw->controls[PVR2_CID_INTERLACE].dirty = !0; + if (!hdw->interlace_val) { + hdw->interlace_val = 0; + hdw->interlace_dirty = !0; } } - if (hdw->controls[PVR2_CID_STDCUR].dirty || - hdw->controls[PVR2_CID_VRES].dirty || - hdw->controls[PVR2_CID_HRES].dirty || - hdw->controls[PVR2_CID_INTERLACE].dirty || - hdw->controls[PVR2_CID_VBR].dirty || - hdw->controls[PVR2_CID_AVERAGEVIDEOBITRATE].dirty || - hdw->controls[PVR2_CID_PEAKVIDEOBITRATE].dirty || - hdw->controls[PVR2_CID_AUDIOBITRATE].dirty || - hdw->controls[PVR2_CID_SRATE].dirty || - hdw->controls[PVR2_CID_AUDIOLAYER].dirty || - hdw->controls[PVR2_CID_AUDIOCRC].dirty || - hdw->controls[PVR2_CID_AUDIOEMPHASIS].dirty) { + if (hdw->std_dirty || + hdw->res_ver_dirty || + hdw->res_hor_dirty || + hdw->interlace_dirty || + hdw->vbr_dirty || + hdw->videobitrate_dirty || + hdw->videopeak_dirty || + hdw->audiobitrate_dirty || + hdw->srate_dirty || + hdw->audiolayer_dirty || + hdw->audiocrc_dirty || + hdw->audioemphasis_dirty) { /* If any of this changes, then the encoder needs to be reconfigured, and we need to reset the stream. */ - stale_subsys_mask |= PVR2_SUBSYS_ENC_CFG; + stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); stale_subsys_mask |= hdw->subsys_stream_mask; } @@ -2306,7 +2104,8 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) for (idx = 0; idx < CTRL_COUNT; idx++) { cptr = hdw->controls + idx; - cptr->dirty = 0; + if (!cptr->info->clear_dirty) continue; + cptr->info->clear_dirty(cptr); } /* Now execute i2c core update */ @@ -2374,7 +2173,7 @@ const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw) { unsigned int msk = 0; - switch (hdw->controls[PVR2_CID_INPUT].value) { + switch (hdw->input_val) { case PVR2_CVAL_INPUT_TV: case PVR2_CVAL_INPUT_RADIO: if (hdw->decoder_ctrl && @@ -2398,42 +2197,6 @@ unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw) } -static int pvr2_ctl_get_subsys_mask(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->subsys_enabled_mask; -} - - -static int pvr2_ctl_set_subsys_mask(struct pvr2_ctrl *cptr,int val) -{ - pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,~0,val); - return 0; -} - - -static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->subsys_stream_mask; -} - - -static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_ctrl *cptr, - int val) -{ - pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,~0,val); - return 0; -} - - -static int pvr2_ctl_get_hsm(struct pvr2_ctrl *cptr) -{ - int result = pvr2_hdw_is_hsm(cptr->hdw); - if (result < 0) return PVR2_CVAL_HSM_FAIL; - if (result) return PVR2_CVAL_HSM_HIGH; - return PVR2_CVAL_HSM_FULL; -} - - int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw) { int result; @@ -2449,13 +2212,6 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw) } -static int pvr2_ctl_get_signal(struct pvr2_ctrl *cptr) -{ - return ((pvr2_hdw_get_signal_status_internal(cptr->hdw) & - PVR2_SIGNAL_OK) ? 1 : 0); -} - - /* Return bit mask indicating signal status */ unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw) { @@ -3124,8 +2880,8 @@ int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) if (!status) { hdw->subsys_enabled_mask = ((hdw->subsys_enabled_mask & - ~PVR2_SUBSYS_USBSTREAM_RUN) | - (runFl ? PVR2_SUBSYS_USBSTREAM_RUN : 0)); + ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) | + (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0)); } return status; } |